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
This commit is contained in:
Lee Salzman
2021-11-11 07:16:58 +00:00
parent 413c23c3c7
commit 6421f4ca8a
20 changed files with 2566 additions and 38 deletions

View File

@@ -3172,6 +3172,14 @@ void ClientWebGLContext::BufferData(GLenum target,
Run<RPROC(BufferData)>(target, RawBuffer<>(range), usage);
}
void ClientWebGLContext::RawBufferData(GLenum target,
const Range<const uint8_t>& srcData,
GLenum usage) {
const FuncScope funcScope(*this, "bufferData");
Run<RPROC(BufferData)>(target, RawBuffer<>(srcData), usage);
}
////
void ClientWebGLContext::BufferSubData(GLenum target,
@@ -4085,6 +4093,14 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
scopedArr.Reset(); // (For the hazard analysis) Done with the data.
}
void ClientWebGLContext::RawTexImage(
uint32_t level, GLenum respecFormat, uvec3 offset,
const webgl::PackingInfo& pi, const webgl::TexUnpackBlobDesc& desc) const {
const FuncScope funcScope(*this, "tex(Sub)Image[23]D");
if (IsContextLost()) return;
Run<RPROC(TexImage)>(level, respecFormat, offset, pi, desc);
}
void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
GLenum imageTarget, GLint level,
GLenum format, const ivec3& offset,