Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* 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_GFX_DRAWTARGETWEBGL_H
|
|
|
|
#define _MOZILLA_GFX_DRAWTARGETWEBGL_H
|
|
|
|
|
2023-10-06 18:12:48 +03:00
|
|
|
#include "GLTypes.h"
|
|
|
|
#include "mozilla/Array.h"
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
#include "mozilla/gfx/2D.h"
|
2022-09-12 18:26:03 +03:00
|
|
|
#include "mozilla/gfx/PathSkia.h"
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
#include "mozilla/LinkedList.h"
|
2022-02-11 22:49:55 +03:00
|
|
|
#include "mozilla/WeakPtr.h"
|
2022-03-15 20:37:30 +03:00
|
|
|
#include "mozilla/ThreadLocal.h"
|
2022-07-12 12:25:35 +03:00
|
|
|
#include "mozilla/ipc/Shmem.h"
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
#include <vector>
|
|
|
|
|
2022-12-07 03:53:55 +03:00
|
|
|
namespace WGR {
|
|
|
|
struct OutputVertex;
|
|
|
|
}
|
|
|
|
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
class ClientWebGLContext;
|
|
|
|
class WebGLBufferJS;
|
2022-02-11 22:49:55 +03:00
|
|
|
class WebGLFramebufferJS;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
class WebGLProgramJS;
|
2022-02-11 22:49:55 +03:00
|
|
|
class WebGLRenderbufferJS;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
class WebGLTextureJS;
|
|
|
|
class WebGLUniformLocationJS;
|
|
|
|
class WebGLVertexArrayJS;
|
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
namespace layers {
|
|
|
|
class SurfaceDescriptor;
|
|
|
|
}
|
|
|
|
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
namespace gfx {
|
|
|
|
|
|
|
|
class DataSourceSurface;
|
|
|
|
class DrawTargetSkia;
|
|
|
|
class DrawTargetWebgl;
|
2022-01-14 20:30:21 +03:00
|
|
|
class PathSkia;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
class SourceSurfaceSkia;
|
2022-02-11 22:49:55 +03:00
|
|
|
class SourceSurfaceWebgl;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
|
|
|
class TextureHandle;
|
|
|
|
class SharedTexture;
|
|
|
|
class SharedTextureHandle;
|
|
|
|
class StandaloneTexture;
|
|
|
|
class GlyphCache;
|
2022-01-14 20:30:21 +03:00
|
|
|
class PathCache;
|
2022-11-12 11:06:44 +03:00
|
|
|
struct PathVertexRange;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
|
|
|
// DrawTargetWebgl implements a subset of the DrawTarget API suitable for use
|
|
|
|
// by CanvasRenderingContext2D. It maps these to a client WebGL context so that
|
|
|
|
// they can be accelerated where possible by WebGL. It manages both routing to
|
|
|
|
// appropriate shaders and texture allocation/caching for surfaces. For commands
|
|
|
|
// that are not feasible to accelerate with WebGL, it mirrors state to a backup
|
2022-02-11 22:49:55 +03:00
|
|
|
// DrawTargetSkia that can be used as a fallback software renderer. Multiple
|
|
|
|
// instances of DrawTargetWebgl within a process will actually share a single
|
|
|
|
// WebGL context so that data can be more easily interchanged between them and
|
|
|
|
// also to enable more reasonable limiting of resource usage.
|
|
|
|
class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
friend class SharedTextureHandle;
|
|
|
|
friend class StandaloneTexture;
|
2022-02-11 22:49:55 +03:00
|
|
|
friend class TextureHandle;
|
2022-02-11 22:49:55 +03:00
|
|
|
friend class SourceSurfaceWebgl;
|
2022-02-21 20:33:09 +03:00
|
|
|
friend class AutoSaveContext;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
|
|
|
public:
|
|
|
|
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetWebgl, override)
|
|
|
|
|
|
|
|
private:
|
|
|
|
IntSize mSize;
|
2022-02-11 22:49:55 +03:00
|
|
|
RefPtr<WebGLFramebufferJS> mFramebuffer;
|
|
|
|
RefPtr<WebGLTextureJS> mTex;
|
2022-09-06 08:06:18 +03:00
|
|
|
RefPtr<WebGLTextureJS> mClipMask;
|
2023-04-05 18:52:36 +03:00
|
|
|
// The integer-aligned, scissor-compatible conservative bounds of the clip.
|
2022-09-06 08:06:18 +03:00
|
|
|
IntRect mClipBounds;
|
2023-04-05 18:52:36 +03:00
|
|
|
// The fractional, AA'd bounds of the clip rect, if applicable.
|
|
|
|
Rect mClipAARect;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
RefPtr<DrawTargetSkia> mSkia;
|
2023-01-28 14:24:54 +03:00
|
|
|
// Skia DT pointing to the same pixel data, but without any applied clips.
|
|
|
|
RefPtr<DrawTargetSkia> mSkiaNoClip;
|
2022-07-12 12:25:35 +03:00
|
|
|
// The Shmem backing the Skia DT, if applicable.
|
|
|
|
mozilla::ipc::Shmem mShmem;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
// The currently cached snapshot of the WebGL context
|
|
|
|
RefPtr<DataSourceSurface> mSnapshot;
|
2023-03-07 11:51:44 +03:00
|
|
|
// Whether the framebuffer is still in the initially clear state.
|
|
|
|
bool mIsClear = true;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
// Whether or not the Skia target has valid contents and is being drawn to
|
|
|
|
bool mSkiaValid = false;
|
2022-01-14 20:30:21 +03:00
|
|
|
// Whether or not Skia layering over the WebGL context is enabled
|
|
|
|
bool mSkiaLayer = false;
|
2023-03-07 11:51:44 +03:00
|
|
|
// Whether the WebGL target was clear when the Skia layer was established.
|
|
|
|
bool mSkiaLayerClear = false;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
// Whether or not the WebGL context has valid contents and is being drawn to
|
2022-07-26 16:41:32 +03:00
|
|
|
bool mWebglValid = true;
|
2022-02-11 22:49:55 +03:00
|
|
|
// Whether or not the clip state has changed since last used by SharedContext.
|
2022-09-12 18:26:02 +03:00
|
|
|
bool mClipChanged = true;
|
|
|
|
// Whether or not the clip state needs to be refreshed. Sometimes the clip
|
|
|
|
// state may be overwritten and require a refresh later, even though it has
|
|
|
|
// not changed.
|
|
|
|
bool mRefreshClipState = true;
|
2022-02-21 20:33:09 +03:00
|
|
|
// The framebuffer has been modified and should be copied to the swap chain.
|
|
|
|
bool mNeedsPresent = true;
|
2022-06-17 00:37:41 +03:00
|
|
|
// The number of layers currently pushed.
|
|
|
|
int32_t mLayerDepth = 0;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
|
|
|
RefPtr<TextureHandle> mSnapshotTexture;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2022-09-12 18:26:03 +03:00
|
|
|
// Store a log of clips currently pushed so that they can be used to init
|
|
|
|
// the clip state of temporary DTs.
|
|
|
|
struct ClipStack {
|
|
|
|
Matrix mTransform;
|
|
|
|
Rect mRect;
|
|
|
|
RefPtr<const Path> mPath;
|
2022-11-28 20:55:07 +03:00
|
|
|
|
|
|
|
bool operator==(const ClipStack& aOther) const;
|
2022-09-12 18:26:03 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<ClipStack> mClipStack;
|
|
|
|
|
2022-11-28 20:55:07 +03:00
|
|
|
// The previous state of the clip stack when a mask was generated.
|
|
|
|
std::vector<ClipStack> mCachedClipStack;
|
|
|
|
|
2022-04-04 18:50:48 +03:00
|
|
|
// UsageProfile stores per-frame counters for significant profiling events
|
|
|
|
// that assist in determining whether acceleration should still be used for
|
|
|
|
// a Canvas2D user.
|
|
|
|
struct UsageProfile {
|
|
|
|
uint32_t mFailedFrames = 0;
|
|
|
|
uint32_t mFrameCount = 0;
|
|
|
|
uint32_t mCacheMisses = 0;
|
|
|
|
uint32_t mCacheHits = 0;
|
|
|
|
uint32_t mUncachedDraws = 0;
|
|
|
|
uint32_t mLayers = 0;
|
|
|
|
uint32_t mReadbacks = 0;
|
|
|
|
uint32_t mFallbacks = 0;
|
|
|
|
|
|
|
|
void BeginFrame();
|
|
|
|
void EndFrame();
|
|
|
|
bool RequiresRefresh() const;
|
|
|
|
|
|
|
|
void OnCacheMiss() { ++mCacheMisses; }
|
|
|
|
void OnCacheHit() { ++mCacheHits; }
|
|
|
|
void OnUncachedDraw() { ++mUncachedDraws; }
|
|
|
|
void OnLayer() { ++mLayers; }
|
|
|
|
void OnReadback() { ++mReadbacks; }
|
|
|
|
void OnFallback() { ++mFallbacks; }
|
|
|
|
};
|
|
|
|
|
|
|
|
UsageProfile mProfile;
|
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
// SharedContext stores most of the actual WebGL state that may be used by
|
|
|
|
// any number of DrawTargetWebgl's that use it. Foremost, it holds the actual
|
|
|
|
// WebGL client context, programs, and buffers for mapping to WebGL.
|
|
|
|
// Secondarily, it holds shared caches for surfaces, glyphs, paths, and
|
|
|
|
// shadows so that each DrawTargetWebgl does not require its own cache. It is
|
|
|
|
// important that SetTarget is called to install the current DrawTargetWebgl
|
|
|
|
// before actually using the SharedContext, as the individual framebuffers
|
|
|
|
// and viewport are still maintained in DrawTargetWebgl itself.
|
|
|
|
class SharedContext : public mozilla::RefCounted<SharedContext>,
|
|
|
|
public mozilla::SupportsWeakPtr {
|
|
|
|
public:
|
|
|
|
MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedContext)
|
|
|
|
|
|
|
|
SharedContext();
|
|
|
|
~SharedContext();
|
|
|
|
|
|
|
|
WeakPtr<DrawTargetWebgl> mCurrentTarget;
|
|
|
|
IntSize mViewportSize;
|
2023-04-05 18:52:36 +03:00
|
|
|
// The current integer-aligned scissor rect.
|
2022-02-11 22:49:55 +03:00
|
|
|
IntRect mClipRect;
|
2023-04-05 18:52:36 +03:00
|
|
|
// The current fractional AA'd clip rect bounds.
|
|
|
|
Rect mClipAARect;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
|
|
|
RefPtr<ClientWebGLContext> mWebgl;
|
|
|
|
|
|
|
|
// Avoid spurious state changes by caching last used state.
|
|
|
|
RefPtr<WebGLProgramJS> mLastProgram;
|
|
|
|
RefPtr<WebGLTextureJS> mLastTexture;
|
2022-09-06 08:06:18 +03:00
|
|
|
RefPtr<WebGLTextureJS> mLastClipMask;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
|
|
|
// WebGL shader resources
|
2022-11-12 11:06:44 +03:00
|
|
|
RefPtr<WebGLBufferJS> mPathVertexBuffer;
|
|
|
|
RefPtr<WebGLVertexArrayJS> mPathVertexArray;
|
|
|
|
// The current insertion offset into the GPU path buffer.
|
|
|
|
uint32_t mPathVertexOffset = 0;
|
|
|
|
// The maximum size of the GPU path buffer.
|
|
|
|
uint32_t mPathVertexCapacity = 0;
|
2022-11-22 08:25:59 +03:00
|
|
|
// The maximum supported type complexity of a GPU path.
|
|
|
|
uint32_t mPathMaxComplexity = 0;
|
2022-12-03 11:21:50 +03:00
|
|
|
// Whether to accelerate stroked paths with AAStroke.
|
|
|
|
bool mPathAAStroke = true;
|
|
|
|
// Whether to accelerate stroked paths with WGR.
|
|
|
|
bool mPathWGRStroke = false;
|
2022-12-07 03:53:55 +03:00
|
|
|
// Temporary buffer for generating WGR output into.
|
|
|
|
UniquePtr<WGR::OutputVertex[]> mWGROutputBuffer;
|
2022-02-11 22:49:55 +03:00
|
|
|
RefPtr<WebGLProgramJS> mSolidProgram;
|
2022-04-16 06:50:26 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mSolidProgramViewport;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mSolidProgramAA;
|
2022-02-11 22:49:55 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mSolidProgramTransform;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mSolidProgramColor;
|
2022-09-06 08:06:18 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mSolidProgramClipMask;
|
2023-04-05 18:52:36 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mSolidProgramClipBounds;
|
2022-02-11 22:49:55 +03:00
|
|
|
RefPtr<WebGLProgramJS> mImageProgram;
|
2022-04-16 06:50:26 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramViewport;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramAA;
|
2022-02-11 22:49:55 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramTransform;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramTexMatrix;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramTexBounds;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramColor;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramSwizzle;
|
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramSampler;
|
2022-09-06 08:06:18 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramClipMask;
|
2023-04-05 18:52:36 +03:00
|
|
|
RefPtr<WebGLUniformLocationJS> mImageProgramClipBounds;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2023-10-06 18:12:48 +03:00
|
|
|
struct SolidProgramUniformState {
|
|
|
|
Maybe<Array<float, 2>> mViewport;
|
|
|
|
Maybe<Array<float, 1>> mAA;
|
|
|
|
Maybe<Array<float, 6>> mTransform;
|
|
|
|
Maybe<Array<float, 4>> mColor;
|
|
|
|
Maybe<Array<float, 4>> mClipBounds;
|
|
|
|
} mSolidProgramUniformState;
|
|
|
|
|
|
|
|
struct ImageProgramUniformState {
|
|
|
|
Maybe<Array<float, 2>> mViewport;
|
|
|
|
Maybe<Array<float, 1>> mAA;
|
|
|
|
Maybe<Array<float, 6>> mTransform;
|
|
|
|
Maybe<Array<float, 6>> mTexMatrix;
|
|
|
|
Maybe<Array<float, 4>> mTexBounds;
|
|
|
|
Maybe<Array<float, 4>> mColor;
|
|
|
|
Maybe<Array<float, 1>> mSwizzle;
|
|
|
|
Maybe<Array<float, 4>> mClipBounds;
|
|
|
|
} mImageProgramUniformState;
|
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
// Scratch framebuffer used to wrap textures for miscellaneous utility ops.
|
|
|
|
RefPtr<WebGLFramebufferJS> mScratchFramebuffer;
|
2022-05-11 20:22:22 +03:00
|
|
|
// Buffer filled with zero data for initializing textures.
|
|
|
|
RefPtr<WebGLBufferJS> mZeroBuffer;
|
2022-09-12 18:26:03 +03:00
|
|
|
size_t mZeroSize = 0;
|
2022-09-06 08:06:18 +03:00
|
|
|
// 1x1 texture with solid white mask for disabling clipping
|
|
|
|
RefPtr<WebGLTextureJS> mNoClipMask;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
uint32_t mMaxTextureSize = 0;
|
2023-01-27 04:45:17 +03:00
|
|
|
bool mRasterizationTruncates = false;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2022-05-27 19:07:15 +03:00
|
|
|
// The current blending operation.
|
2022-02-11 22:49:55 +03:00
|
|
|
CompositionOp mLastCompositionOp = CompositionOp::OP_SOURCE;
|
2022-05-27 19:07:15 +03:00
|
|
|
// The constant blend color used for the blending operation.
|
|
|
|
Maybe<DeviceColor> mLastBlendColor;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2023-04-20 17:27:52 +03:00
|
|
|
// The cached scissor state. Operations that rely on scissor state should
|
|
|
|
// take care to enable or disable the cached scissor state as necessary.
|
|
|
|
bool mScissorEnabled = false;
|
|
|
|
IntRect mLastScissor = {-1, -1, -1, -1};
|
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
// A most-recently-used list of allocated texture handles.
|
|
|
|
LinkedList<RefPtr<TextureHandle>> mTextureHandles;
|
|
|
|
size_t mNumTextureHandles = 0;
|
|
|
|
// User data key linking a SourceSurface with its TextureHandle.
|
|
|
|
UserDataKey mTextureHandleKey = {0};
|
|
|
|
// User data key linking a SourceSurface with its shadow blur TextureHandle.
|
|
|
|
UserDataKey mShadowTextureKey = {0};
|
|
|
|
// User data key linking a ScaledFont with its GlyphCache.
|
|
|
|
UserDataKey mGlyphCacheKey = {0};
|
|
|
|
// List of all GlyphCaches currently allocated to fonts.
|
|
|
|
LinkedList<GlyphCache> mGlyphCaches;
|
|
|
|
// Cache of rasterized paths.
|
|
|
|
UniquePtr<PathCache> mPathCache;
|
|
|
|
// Collection of allocated shared texture pages that may be shared amongst
|
|
|
|
// many handles.
|
|
|
|
std::vector<RefPtr<SharedTexture>> mSharedTextures;
|
|
|
|
// Collection of allocated standalone textures that have a single assigned
|
|
|
|
// handle.
|
|
|
|
std::vector<RefPtr<StandaloneTexture>> mStandaloneTextures;
|
|
|
|
size_t mUsedTextureMemory = 0;
|
|
|
|
size_t mTotalTextureMemory = 0;
|
2022-05-11 20:22:21 +03:00
|
|
|
// The total reserved memory for empty texture pages that are kept around
|
|
|
|
// for future allocations.
|
|
|
|
size_t mEmptyTextureMemory = 0;
|
2022-05-11 20:22:22 +03:00
|
|
|
// A memory pressure event may signal from another thread that caches should
|
|
|
|
// be cleared if possible.
|
|
|
|
Atomic<bool> mShouldClearCaches;
|
2022-07-12 12:25:35 +03:00
|
|
|
// Whether the Shmem is currently being processed by the remote side. If so,
|
|
|
|
// we need to wait for processing to complete before any further commands
|
|
|
|
// modifying the Skia DT can proceed.
|
|
|
|
bool mWaitForShmem = false;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
|
|
|
const Matrix& GetTransform() const { return mCurrentTarget->mTransform; }
|
|
|
|
|
|
|
|
bool IsContextLost() const;
|
|
|
|
|
|
|
|
bool Initialize();
|
|
|
|
bool CreateShaders();
|
2022-12-07 03:53:55 +03:00
|
|
|
void ResetPathVertexBuffer(bool aChanged = true);
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2022-05-27 19:07:15 +03:00
|
|
|
void SetBlendState(CompositionOp aOp,
|
|
|
|
const Maybe<DeviceColor>& aBlendColor = Nothing());
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2023-04-05 18:52:36 +03:00
|
|
|
void SetClipRect(const Rect& aClipRect);
|
|
|
|
void SetClipRect(const IntRect& aClipRect) { SetClipRect(Rect(aClipRect)); }
|
2022-09-06 08:06:18 +03:00
|
|
|
bool SetClipMask(const RefPtr<WebGLTextureJS>& aTex);
|
|
|
|
bool SetNoClipMask();
|
|
|
|
bool HasClipMask() const {
|
|
|
|
return mLastClipMask && mLastClipMask != mNoClipMask;
|
|
|
|
}
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2023-10-06 18:12:48 +03:00
|
|
|
// Avoids redundant UniformData calls by caching the previously set value.
|
|
|
|
template <class T, size_t N>
|
|
|
|
void MaybeUniformData(GLenum aFuncElemType,
|
|
|
|
const WebGLUniformLocationJS* const aLoc,
|
|
|
|
const Array<T, N>& aData,
|
|
|
|
Maybe<Array<T, N>>& aCached);
|
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
bool IsCurrentTarget(DrawTargetWebgl* aDT) const {
|
|
|
|
return aDT == mCurrentTarget;
|
|
|
|
}
|
|
|
|
bool SetTarget(DrawTargetWebgl* aDT);
|
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
// Reset the current target.
|
2022-02-11 22:49:55 +03:00
|
|
|
void ClearTarget() { mCurrentTarget = nullptr; }
|
2022-02-11 22:49:55 +03:00
|
|
|
// Reset the last used texture to force binding next use.
|
2023-09-04 20:39:16 +03:00
|
|
|
void ClearLastTexture(bool aFullClear = false);
|
2022-02-11 22:49:55 +03:00
|
|
|
|
|
|
|
bool SupportsPattern(const Pattern& aPattern);
|
|
|
|
|
2023-04-20 17:27:52 +03:00
|
|
|
void EnableScissor(const IntRect& aRect);
|
|
|
|
void DisableScissor();
|
|
|
|
|
2022-07-26 04:27:04 +03:00
|
|
|
void SetTexFilter(WebGLTextureJS* aTex, bool aFilter);
|
2022-09-06 08:06:18 +03:00
|
|
|
void InitTexParameters(WebGLTextureJS* aTex, bool aFilter = true);
|
2022-02-11 22:49:55 +03:00
|
|
|
|
|
|
|
bool ReadInto(uint8_t* aDstData, int32_t aDstStride, SurfaceFormat aFormat,
|
|
|
|
const IntRect& aBounds, TextureHandle* aHandle = nullptr);
|
|
|
|
already_AddRefed<DataSourceSurface> ReadSnapshot(
|
|
|
|
TextureHandle* aHandle = nullptr);
|
|
|
|
already_AddRefed<TextureHandle> WrapSnapshot(const IntSize& aSize,
|
|
|
|
SurfaceFormat aFormat,
|
|
|
|
RefPtr<WebGLTextureJS> aTex);
|
2022-12-08 00:06:32 +03:00
|
|
|
already_AddRefed<TextureHandle> CopySnapshot(
|
|
|
|
const IntRect& aRect, TextureHandle* aHandle = nullptr);
|
2022-02-11 22:49:55 +03:00
|
|
|
|
|
|
|
already_AddRefed<WebGLTextureJS> GetCompatibleSnapshot(
|
2023-03-07 11:51:44 +03:00
|
|
|
SourceSurface* aSurface) const;
|
|
|
|
bool IsCompatibleSurface(SourceSurface* aSurface) const;
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2022-02-21 20:33:09 +03:00
|
|
|
bool UploadSurface(DataSourceSurface* aData, SurfaceFormat aFormat,
|
|
|
|
const IntRect& aSrcRect, const IntPoint& aDstOffset,
|
2023-03-07 11:51:44 +03:00
|
|
|
bool aInit, bool aZero = false,
|
|
|
|
const RefPtr<WebGLTextureJS>& aTex = nullptr);
|
2023-06-07 22:47:04 +03:00
|
|
|
already_AddRefed<TextureHandle> AllocateTextureHandle(
|
|
|
|
SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared = true,
|
|
|
|
bool aRenderable = false);
|
2022-02-11 22:49:55 +03:00
|
|
|
bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions,
|
|
|
|
Maybe<DeviceColor> aMaskColor = Nothing(),
|
|
|
|
RefPtr<TextureHandle>* aHandle = nullptr,
|
|
|
|
bool aTransformed = true, bool aClipped = true,
|
|
|
|
bool aAccelOnly = false, bool aForceUpdate = false,
|
2022-11-12 11:06:44 +03:00
|
|
|
const StrokeOptions* aStrokeOptions = nullptr,
|
|
|
|
const PathVertexRange* aVertexRange = nullptr);
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2023-06-07 22:47:04 +03:00
|
|
|
already_AddRefed<TextureHandle> DrawStrokeMask(
|
|
|
|
const PathVertexRange& aVertexRange, const IntSize& aSize);
|
2022-02-11 22:49:55 +03:00
|
|
|
bool DrawPathAccel(const Path* aPath, const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions,
|
2022-04-01 22:03:29 +03:00
|
|
|
const StrokeOptions* aStrokeOptions = nullptr,
|
2023-06-10 21:30:47 +03:00
|
|
|
bool aAllowStrokeAlpha = false,
|
2022-04-01 22:03:29 +03:00
|
|
|
const ShadowOptions* aShadow = nullptr,
|
|
|
|
bool aCacheable = true);
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2022-09-06 08:06:17 +03:00
|
|
|
bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer,
|
2022-02-21 20:33:09 +03:00
|
|
|
const Pattern& aPattern, const DrawOptions& aOptions,
|
2022-09-06 08:06:17 +03:00
|
|
|
const StrokeOptions* aStrokeOptions,
|
2022-02-21 20:33:09 +03:00
|
|
|
bool aUseSubpixelAA);
|
2022-02-11 22:49:55 +03:00
|
|
|
|
2022-02-11 22:49:56 +03:00
|
|
|
void PruneTextureHandle(const RefPtr<TextureHandle>& aHandle);
|
2022-02-11 22:49:55 +03:00
|
|
|
bool PruneTextureMemory(size_t aMargin = 0, bool aPruneUnused = true);
|
|
|
|
|
|
|
|
bool RemoveSharedTexture(const RefPtr<SharedTexture>& aTexture);
|
|
|
|
bool RemoveStandaloneTexture(const RefPtr<StandaloneTexture>& aTexture);
|
|
|
|
|
|
|
|
void UnlinkSurfaceTextures();
|
|
|
|
void UnlinkSurfaceTexture(const RefPtr<TextureHandle>& aHandle);
|
|
|
|
void UnlinkGlyphCaches();
|
2022-05-11 20:22:22 +03:00
|
|
|
|
|
|
|
void OnMemoryPressure();
|
|
|
|
void ClearAllTextures();
|
|
|
|
void ClearEmptyTextureMemory();
|
|
|
|
void ClearCachesIfNecessary();
|
2022-07-12 12:25:35 +03:00
|
|
|
|
2022-11-08 19:23:56 +03:00
|
|
|
void WaitForShmem(DrawTargetWebgl* aTarget);
|
2022-11-12 11:06:44 +03:00
|
|
|
|
|
|
|
void CachePrefs();
|
2022-02-11 22:49:55 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
RefPtr<SharedContext> mSharedContext;
|
|
|
|
|
2022-03-15 20:37:30 +03:00
|
|
|
static MOZ_THREAD_LOCAL(SharedContext*) sSharedContext;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
2022-10-14 23:06:20 +03:00
|
|
|
// Try to keep around the shared context for the main thread in case canvases
|
|
|
|
// are rapidly recreated and destroyed.
|
|
|
|
static RefPtr<SharedContext> sMainSharedContext;
|
|
|
|
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
public:
|
|
|
|
DrawTargetWebgl();
|
|
|
|
~DrawTargetWebgl();
|
|
|
|
|
|
|
|
static already_AddRefed<DrawTargetWebgl> Create(const IntSize& aSize,
|
|
|
|
SurfaceFormat aFormat);
|
|
|
|
|
|
|
|
bool Init(const IntSize& aSize, SurfaceFormat aFormat);
|
|
|
|
|
2021-11-30 19:59:42 +03:00
|
|
|
bool IsValid() const override;
|
|
|
|
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
DrawTargetType GetType() const override {
|
|
|
|
return DrawTargetType::HARDWARE_RASTER;
|
|
|
|
}
|
|
|
|
BackendType GetBackendType() const override { return BackendType::WEBGL; }
|
|
|
|
IntSize GetSize() const override { return mSize; }
|
|
|
|
|
2022-07-26 04:28:48 +03:00
|
|
|
already_AddRefed<SourceSurface> GetDataSnapshot();
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
already_AddRefed<SourceSurface> Snapshot() override;
|
2022-11-17 06:07:18 +03:00
|
|
|
already_AddRefed<SourceSurface> GetOptimizedSnapshot(DrawTarget* aTarget);
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
already_AddRefed<SourceSurface> GetBackingSurface() override;
|
2022-02-21 20:33:09 +03:00
|
|
|
void DetachAllSnapshots() override;
|
|
|
|
|
|
|
|
void BeginFrame(const IntRect& aPersistedRect);
|
|
|
|
void EndFrame();
|
2022-04-04 18:50:48 +03:00
|
|
|
bool RequiresRefresh() const { return mProfile.RequiresRefresh(); }
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
|
|
|
bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride,
|
|
|
|
SurfaceFormat* aFormat, IntPoint* aOrigin = nullptr) override;
|
|
|
|
void ReleaseBits(uint8_t* aData) override;
|
|
|
|
|
2022-02-21 20:33:09 +03:00
|
|
|
void Flush() override {}
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
void DrawSurface(
|
|
|
|
SourceSurface* aSurface, const Rect& aDest, const Rect& aSource,
|
|
|
|
const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
|
|
|
|
const Point& aDestPoint,
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void DrawSurfaceWithShadow(SourceSurface* aSurface, const Point& aDest,
|
2022-04-01 22:03:29 +03:00
|
|
|
const ShadowOptions& aShadow,
|
|
|
|
CompositionOp aOperator) override;
|
|
|
|
void DrawShadow(const Path* aPath, const Pattern& aPattern,
|
|
|
|
const ShadowOptions& aShadow, const DrawOptions& aOptions,
|
|
|
|
const StrokeOptions* aStrokeOptions = nullptr) override;
|
|
|
|
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
void ClearRect(const Rect& aRect) override;
|
|
|
|
void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
|
|
|
|
const IntPoint& aDestination) override;
|
|
|
|
void FillRect(const Rect& aRect, const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void StrokeRect(const Rect& aRect, const Pattern& aPattern,
|
|
|
|
const StrokeOptions& aStrokeOptions = StrokeOptions(),
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
2022-09-08 23:02:17 +03:00
|
|
|
bool StrokeLineAccel(const Point& aStart, const Point& aEnd,
|
|
|
|
const Pattern& aPattern,
|
|
|
|
const StrokeOptions& aStrokeOptions,
|
2023-02-21 21:03:37 +03:00
|
|
|
const DrawOptions& aOptions, bool aClosed = false);
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
void StrokeLine(const Point& aStart, const Point& aEnd,
|
|
|
|
const Pattern& aPattern,
|
|
|
|
const StrokeOptions& aStrokeOptions = StrokeOptions(),
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void Stroke(const Path* aPath, const Pattern& aPattern,
|
|
|
|
const StrokeOptions& aStrokeOptions = StrokeOptions(),
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void Fill(const Path* aPath, const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
|
|
|
|
void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
|
|
|
|
void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
|
|
|
|
const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
|
|
|
|
const Pattern& aPattern,
|
|
|
|
const StrokeOptions& aStrokeOptions = StrokeOptions(),
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void Mask(const Pattern& aSource, const Pattern& aMask,
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset,
|
|
|
|
const DrawOptions& aOptions = DrawOptions()) override;
|
|
|
|
bool Draw3DTransformedSurface(SourceSurface* aSurface,
|
|
|
|
const Matrix4x4& aMatrix) override;
|
|
|
|
void PushClip(const Path* aPath) override;
|
|
|
|
void PushClipRect(const Rect& aRect) override;
|
|
|
|
void PushDeviceSpaceClipRects(const IntRect* aRects,
|
|
|
|
uint32_t aCount) override;
|
|
|
|
void PopClip() override;
|
2022-11-17 06:10:35 +03:00
|
|
|
bool RemoveAllClips() override;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
|
|
|
|
const Matrix& aMaskTransform,
|
|
|
|
const IntRect& aBounds = IntRect(),
|
2022-06-17 00:37:41 +03:00
|
|
|
bool aCopyBackground = false) override;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
void PushLayerWithBlend(
|
|
|
|
bool aOpaque, Float aOpacity, SourceSurface* aMask,
|
|
|
|
const Matrix& aMaskTransform, const IntRect& aBounds = IntRect(),
|
|
|
|
bool aCopyBackground = false,
|
2022-06-17 00:37:41 +03:00
|
|
|
CompositionOp aCompositionOp = CompositionOp::OP_OVER) override;
|
|
|
|
void PopLayer() override;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
|
|
|
|
unsigned char* aData, const IntSize& aSize, int32_t aStride,
|
|
|
|
SurfaceFormat aFormat) const override;
|
|
|
|
already_AddRefed<SourceSurface> OptimizeSourceSurface(
|
|
|
|
SourceSurface* aSurface) const override;
|
|
|
|
already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(
|
|
|
|
SourceSurface* aSurface) const override;
|
|
|
|
already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
|
|
|
|
const NativeSurface& aSurface) const override;
|
|
|
|
already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
|
|
|
|
const IntSize& aSize, SurfaceFormat aFormat) const override;
|
|
|
|
bool CanCreateSimilarDrawTarget(const IntSize& aSize,
|
|
|
|
SurfaceFormat aFormat) const override;
|
|
|
|
RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds,
|
|
|
|
SurfaceFormat aFormat) override;
|
|
|
|
|
|
|
|
already_AddRefed<PathBuilder> CreatePathBuilder(
|
|
|
|
FillRule aFillRule = FillRule::FILL_WINDING) const override;
|
|
|
|
already_AddRefed<GradientStops> CreateGradientStops(
|
|
|
|
GradientStop* aStops, uint32_t aNumStops,
|
|
|
|
ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
|
|
|
|
already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
|
|
|
|
void SetTransform(const Matrix& aTransform) override;
|
|
|
|
void* GetNativeSurface(NativeSurfaceType aType) override;
|
|
|
|
|
2022-02-11 22:49:56 +03:00
|
|
|
Maybe<layers::SurfaceDescriptor> GetFrontBuffer();
|
|
|
|
|
2022-05-11 20:22:22 +03:00
|
|
|
void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); }
|
|
|
|
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
operator std::string() const {
|
|
|
|
std::stringstream stream;
|
|
|
|
stream << "DrawTargetWebgl(" << this << ")";
|
|
|
|
return stream.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2022-02-11 22:49:55 +03:00
|
|
|
bool SupportsPattern(const Pattern& aPattern) {
|
|
|
|
return mSharedContext->SupportsPattern(aPattern);
|
|
|
|
}
|
2022-02-11 18:36:29 +03:00
|
|
|
|
2022-09-06 08:06:18 +03:00
|
|
|
bool SetSimpleClipRect();
|
|
|
|
bool GenerateComplexClipMask();
|
2022-02-11 22:49:55 +03:00
|
|
|
bool PrepareContext(bool aClipped = true);
|
|
|
|
|
|
|
|
void DrawRectFallback(const Rect& aRect, const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions,
|
2023-04-18 18:08:27 +03:00
|
|
|
Maybe<DeviceColor> aMaskColor = Nothing(),
|
|
|
|
bool aTransform = true, bool aClipped = true,
|
|
|
|
const StrokeOptions* aStrokeOptions = nullptr);
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
bool DrawRect(const Rect& aRect, const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions,
|
|
|
|
Maybe<DeviceColor> aMaskColor = Nothing(),
|
|
|
|
RefPtr<TextureHandle>* aHandle = nullptr,
|
|
|
|
bool aTransformed = true, bool aClipped = true,
|
2022-01-14 20:30:20 +03:00
|
|
|
bool aAccelOnly = false, bool aForceUpdate = false,
|
|
|
|
const StrokeOptions* aStrokeOptions = nullptr);
|
2022-11-12 11:06:44 +03:00
|
|
|
|
2023-03-07 11:51:44 +03:00
|
|
|
ColorPattern GetClearPattern() const;
|
|
|
|
|
2023-04-18 18:08:27 +03:00
|
|
|
bool RectContainsViewport(const Rect& aRect) const;
|
|
|
|
|
2022-11-28 23:31:02 +03:00
|
|
|
bool ShouldAccelPath(const DrawOptions& aOptions,
|
|
|
|
const StrokeOptions* aStrokeOptions);
|
2022-01-14 20:30:22 +03:00
|
|
|
void DrawPath(const Path* aPath, const Pattern& aPattern,
|
|
|
|
const DrawOptions& aOptions,
|
2023-06-10 21:30:47 +03:00
|
|
|
const StrokeOptions* aStrokeOptions = nullptr,
|
|
|
|
bool aAllowStrokeAlpha = false);
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
2022-02-21 20:33:09 +03:00
|
|
|
bool MarkChanged();
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
|
|
|
void ReadIntoSkia();
|
2022-01-14 20:30:21 +03:00
|
|
|
void FlattenSkia();
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
bool FlushFromSkia();
|
|
|
|
|
2022-07-12 12:25:35 +03:00
|
|
|
void WaitForShmem() {
|
|
|
|
if (mSharedContext->mWaitForShmem) {
|
2022-11-08 19:23:56 +03:00
|
|
|
mSharedContext->WaitForShmem(this);
|
2022-07-12 12:25:35 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-07 11:51:44 +03:00
|
|
|
void MarkSkiaChanged(bool aOverwrite = false) {
|
2022-07-12 12:25:35 +03:00
|
|
|
WaitForShmem();
|
2023-03-07 11:51:44 +03:00
|
|
|
if (aOverwrite) {
|
|
|
|
mSkiaValid = true;
|
|
|
|
mSkiaLayer = false;
|
|
|
|
} else if (!mSkiaValid) {
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
ReadIntoSkia();
|
2022-01-14 20:30:21 +03:00
|
|
|
} else if (mSkiaLayer) {
|
|
|
|
FlattenSkia();
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
}
|
|
|
|
mWebglValid = false;
|
2023-03-07 11:51:44 +03:00
|
|
|
mIsClear = false;
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
}
|
|
|
|
|
2022-01-14 20:30:21 +03:00
|
|
|
void MarkSkiaChanged(const DrawOptions& aOptions);
|
|
|
|
|
2022-06-09 18:33:21 +03:00
|
|
|
bool ShouldUseSubpixelAA(ScaledFont* aFont, const DrawOptions& aOptions);
|
|
|
|
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
bool ReadInto(uint8_t* aDstData, int32_t aDstStride);
|
2022-02-11 22:49:55 +03:00
|
|
|
already_AddRefed<DataSourceSurface> ReadSnapshot();
|
2022-12-08 00:06:32 +03:00
|
|
|
already_AddRefed<TextureHandle> CopySnapshot(const IntRect& aRect);
|
|
|
|
already_AddRefed<TextureHandle> CopySnapshot() {
|
|
|
|
return CopySnapshot(GetRect());
|
|
|
|
}
|
|
|
|
|
2022-06-02 18:27:00 +03:00
|
|
|
void ClearSnapshot(bool aCopyOnWrite = true, bool aNeedHandle = false);
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
|
2022-02-11 22:49:55 +03:00
|
|
|
bool CreateFramebuffer();
|
2022-02-21 20:33:09 +03:00
|
|
|
|
|
|
|
// PrepareContext may sometimes be used recursively. When this occurs, ensure
|
|
|
|
// that clip state is restored after the context is used.
|
|
|
|
struct AutoRestoreContext {
|
|
|
|
DrawTargetWebgl* mTarget;
|
2023-04-05 18:52:36 +03:00
|
|
|
Rect mClipAARect;
|
2022-09-06 08:06:18 +03:00
|
|
|
RefPtr<WebGLTextureJS> mLastClipMask;
|
2022-02-21 20:33:09 +03:00
|
|
|
|
2022-09-06 08:06:18 +03:00
|
|
|
explicit AutoRestoreContext(DrawTargetWebgl* aTarget);
|
2022-02-21 20:33:09 +03:00
|
|
|
|
2022-09-06 08:06:18 +03:00
|
|
|
~AutoRestoreContext();
|
2022-02-21 20:33:09 +03:00
|
|
|
};
|
Bug 1739448 - Implement a prototype WebGL-backed Canvas2D. r=gfx-reviewers,nical,jrmuizel
This mainly provides DrawTargetWebgl, which implements the subset of the DrawTarget
API necessary for integration with CanvasRenderingContext2D. It translates them to
suitable commands for its internal ClientWebGLContext, which then manages remoting
WebGL requests to the parent/GPU process.
Currently two shaders are used for drawing Canvas2D primitives, but can be expanded
in the future. These are an image shader and a solid color shader.
The core of this implementation revolves around TexturePacker and TextureHandle,
which cope with the necessity of frequently uploading SourceSurfaces for use with
WebGL. TexturePacker implements a bin-packing algorithm for packing these uploads
into texture pages, which can either be SharedTextures if they are reasonably small,
or StandaloneTextures if they are too big to pack in a SharedTexture. Each upload
is assigned a TextureHandle which is used to manage it in a move-to-front cache,
so that we can easily eject TextureHandles from the back of the cache if we have
too many. These TextureHandles are associated with the SourceSurface that spawned
them to more easily manage their lifetimes.
There are further dependent caches for dealing with blurred shadows and with text.
Shadows are cached in an uploaded texture bound to the SourceSurface that generated
them. Text is handled by caching entire runs in the GlyphCache (keyed by both their
rendering parameters and their glyphs). The text is first rasterized to a surface
and then uploaded to a texture in the GlyphCache which can be reused should the
text be encountered again.
To deal with commands we can't accelerate, a separate internal DrawTargetSkia is
also maintained. The content of the WebGL framebuffer is copied into it so that
drawing can then proceed in software from there. It remains in this fallover state
until the next frame, when it resets back to using the WebGL framebuffer again.
This acceleration is disabled by default. To enable it, you must toggle the pref
"gfx.canvas.accelerated" to true. This should be suitably different from the naming
of the previous SkiaGL prefs to not alias with them. There are a few dependent prefs
that follow from the previous SkiaGL prefs for setting the size limitations for
acceleration and also limitations for the internal texture cache.
Differential Revision: https://phabricator.services.mozilla.com/D130388
2021-11-11 10:16:58 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace gfx
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // _MOZILLA_GFX_DRAWTARGETWEBGL_H
|