Update GPUCanvasContext size handling
The spec updated in https://github.com/gpuweb/gpuweb/pull/2826 to remove size from the configuration call. It's now pulled from the Canvas width and height attributes like WebGL. This change deprecates setting the size in configure() and adds missing fields to the dictionary (though neither of them actually work at the moment.) Bug: 1326473 Change-Id: I072b647a85ca46b43b91266674b7bb5bba300135 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3652598 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Brandon Jones <bajones@chromium.org> Reviewed-by: Justin Novosad <junov@chromium.org> Cr-Commit-Position: refs/heads/main@{#1004860}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
1777cf6124
commit
b9f42d88e8
third_party/blink/renderer
core
modules
@ -229,22 +229,24 @@ class CORE_EXPORT CanvasRenderingContext
|
||||
|
||||
// WebGL-specific interface
|
||||
virtual bool UsingSwapChain() const { return false; }
|
||||
virtual void SetFilterQuality(cc::PaintFlags::FilterQuality) { NOTREACHED(); }
|
||||
virtual void Reshape(int width, int height) {}
|
||||
virtual void MarkLayerComposited() { NOTREACHED(); }
|
||||
virtual sk_sp<SkData> PaintRenderingResultsToDataArray(SourceDrawingBuffer) {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
virtual int ExternallyAllocatedBufferCountPerPixel() {
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
virtual gfx::Size DrawingBufferSize() const {
|
||||
NOTREACHED();
|
||||
return gfx::Size(0, 0);
|
||||
}
|
||||
|
||||
// WebGL & WebGPU-specific interface
|
||||
virtual void SetFilterQuality(cc::PaintFlags::FilterQuality) { NOTREACHED(); }
|
||||
virtual void Reshape(int width, int height) {}
|
||||
virtual int ExternallyAllocatedBufferCountPerPixel() {
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OffscreenCanvas-specific methods.
|
||||
virtual bool PushFrame() { return false; }
|
||||
virtual ImageBitmap* TransferToImageBitmap(ScriptState*) { return nullptr; }
|
||||
|
@ -677,7 +677,7 @@ void HTMLCanvasElement::Reset() {
|
||||
|
||||
SetSurfaceSize(new_size);
|
||||
|
||||
if (IsWebGL() && old_size != Size())
|
||||
if ((IsWebGL() || IsWebGPU()) && old_size != Size())
|
||||
context_->Reshape(width(), height());
|
||||
|
||||
if (LayoutObject* layout_object = GetLayoutObject()) {
|
||||
|
@ -177,7 +177,7 @@ void OffscreenCanvas::SetSize(const gfx::Size& size) {
|
||||
if (frame_dispatcher_)
|
||||
frame_dispatcher_->Reshape(size_);
|
||||
if (context_) {
|
||||
if (context_->IsWebGL()) {
|
||||
if (context_->IsWebGL() || IsWebGPU()) {
|
||||
context_->Reshape(size_.width(), size_.height());
|
||||
} else if (context_->IsRenderingContext2D()) {
|
||||
context_->Reset();
|
||||
|
@ -9,10 +9,14 @@ enum GPUCanvasCompositingAlphaMode {
|
||||
"premultiplied",
|
||||
};
|
||||
|
||||
dictionary GPUCanvasConfiguration : GPUObjectDescriptorBase {
|
||||
dictionary GPUCanvasConfiguration {
|
||||
required GPUDevice device;
|
||||
required GPUTextureFormat format;
|
||||
GPUTextureUsageFlags usage = 16; // GPUTextureUsage.RENDER_ATTACHMENT
|
||||
sequence<GPUTextureFormat> viewFormats = [];
|
||||
GPUPredefinedColorSpace colorSpace = "srgb";
|
||||
GPUCanvasCompositingAlphaMode compositingAlphaMode;
|
||||
|
||||
// TODO(crbug.com/1069302): Remove after deprecation period.
|
||||
GPUExtent3D size;
|
||||
};
|
||||
|
@ -74,6 +74,21 @@ cc::Layer* GPUCanvasContext::CcLayer() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GPUCanvasContext::Reshape(int width, int height) {
|
||||
if (stopped_ || !swapchain_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If an explicit size was given during the last call to configure() use that
|
||||
// size instead. This is deprecated behavior.
|
||||
// TODO(crbug.com/1326473): Remove after deprecation period.
|
||||
if (!configured_size_.IsZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReconfigureSwapchain(gfx::Size(width, height));
|
||||
}
|
||||
|
||||
scoped_refptr<StaticBitmapImage> GPUCanvasContext::GetImage() {
|
||||
if (!swapchain_)
|
||||
return nullptr;
|
||||
@ -159,6 +174,8 @@ void GPUCanvasContext::configure(const GPUCanvasConfiguration* descriptor,
|
||||
return;
|
||||
}
|
||||
|
||||
// This needs to happen early so that if any validation fails the swapchain
|
||||
// stays unconfigured.
|
||||
if (swapchain_) {
|
||||
// Tell any previous swapchain that it will no longer be used and can
|
||||
// destroy all its resources (and produce errors when used).
|
||||
@ -170,10 +187,9 @@ void GPUCanvasContext::configure(const GPUCanvasConfiguration* descriptor,
|
||||
// that errors can be generated in the appropriate error scope.
|
||||
configured_device_ = descriptor->device();
|
||||
|
||||
WGPUTextureUsage usage = AsDawnEnum<WGPUTextureUsage>(descriptor->usage());
|
||||
WGPUTextureFormat format =
|
||||
AsDawnEnum<WGPUTextureFormat>(descriptor->format());
|
||||
switch (format) {
|
||||
usage_ = AsDawnEnum<WGPUTextureUsage>(descriptor->usage());
|
||||
format_ = AsDawnEnum<WGPUTextureFormat>(descriptor->format());
|
||||
switch (format_) {
|
||||
case WGPUTextureFormat_BGRA8Unorm:
|
||||
// TODO(crbug.com/1298618): support RGBA8Unorm on MAC.
|
||||
#if !BUILDFLAG(IS_MAC)
|
||||
@ -190,11 +206,44 @@ void GPUCanvasContext::configure(const GPUCanvasConfiguration* descriptor,
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the default size.
|
||||
gfx::Size size;
|
||||
alpha_mode_ = V8GPUCanvasCompositingAlphaMode::Enum::kPremultiplied;
|
||||
if (descriptor->hasCompositingAlphaMode()) {
|
||||
alpha_mode_ = descriptor->compositingAlphaMode().AsEnum();
|
||||
} else {
|
||||
configured_device_->AddConsoleWarning(
|
||||
"The default GPUCanvasCompositingAlphaMode will change from "
|
||||
"\"premultiplied\" to \"opaque\". "
|
||||
"Please explicitly pass \"premultiplied\" if you would like to "
|
||||
"continue using that compositing mode.");
|
||||
}
|
||||
|
||||
// TODO(crbug.com/1326473): Implement support for context viewFormats.
|
||||
if (descriptor->viewFormats().size()) {
|
||||
configured_device_->InjectError(
|
||||
WGPUErrorType_Validation,
|
||||
"Specifying additional viewFormats for GPUCanvasContexts is not "
|
||||
"supported yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Once colorSpaces other than sRGB are defined, we'll need to ensure they're
|
||||
// supported here.
|
||||
DCHECK_EQ(AsDawnEnum(descriptor->colorSpace()),
|
||||
WGPUPredefinedColorSpace_Srgb);
|
||||
|
||||
// Set the size while configuring.
|
||||
if (descriptor->hasSize()) {
|
||||
// TODO(crbug.com/1326473): Remove this branch after deprecation period.
|
||||
configured_device_->AddConsoleWarning(
|
||||
"Setting an explicit size when calling configure() on a "
|
||||
"GPUCanvasContext has been deprecated, and will soon be removed. "
|
||||
"Please set the canvas width and height attributes instead. Note that "
|
||||
"after the initial call to configure() changes to the canvas width and "
|
||||
"height will now take effect without the need to call configure() "
|
||||
"again.");
|
||||
|
||||
WGPUExtent3D dawn_extent = AsDawnType(descriptor->size());
|
||||
size = gfx::Size(dawn_extent.width, dawn_extent.height);
|
||||
configured_size_ = gfx::Size(dawn_extent.width, dawn_extent.height);
|
||||
|
||||
if (dawn_extent.depthOrArrayLayers != 1) {
|
||||
configured_device_->InjectError(
|
||||
@ -202,33 +251,32 @@ void GPUCanvasContext::configure(const GPUCanvasConfiguration* descriptor,
|
||||
"swap chain size must have depthOrArrayLayers set to 1");
|
||||
return;
|
||||
}
|
||||
if (size.IsEmpty()) {
|
||||
if (configured_size_.IsEmpty()) {
|
||||
configured_device_->InjectError(
|
||||
WGPUErrorType_Validation,
|
||||
"context width and height must be greater than 0");
|
||||
return;
|
||||
}
|
||||
|
||||
ReconfigureSwapchain(configured_size_);
|
||||
} else {
|
||||
size = Host()->Size();
|
||||
configured_size_.SetSize(0, 0);
|
||||
ReconfigureSwapchain(Host()->Size());
|
||||
}
|
||||
}
|
||||
|
||||
void GPUCanvasContext::ReconfigureSwapchain(gfx::Size size) {
|
||||
if (swapchain_) {
|
||||
// Tell any previous swapchain that it will no longer be used and can
|
||||
// destroy all its resources (and produce errors when used).
|
||||
swapchain_->Neuter();
|
||||
swapchain_ = nullptr;
|
||||
}
|
||||
|
||||
V8GPUCanvasCompositingAlphaMode::Enum alpha_mode =
|
||||
V8GPUCanvasCompositingAlphaMode::Enum::kPremultiplied;
|
||||
if (descriptor->hasCompositingAlphaMode()) {
|
||||
alpha_mode = descriptor->compositingAlphaMode().AsEnum();
|
||||
} else {
|
||||
configured_device_->AddConsoleWarning(
|
||||
"The default GPUCanvasCompositingAlphaMode will change from \"premultiplied\" to \"opaque\". "
|
||||
"Please explicitly pass \"premultiplied\" if you would like to "
|
||||
"continue using that compositing mode.");
|
||||
}
|
||||
swapchain_ = MakeGarbageCollected<GPUSwapChain>(
|
||||
this, configured_device_, usage, format, filter_quality_, alpha_mode,
|
||||
this, configured_device_, usage_, format_, filter_quality_, alpha_mode_,
|
||||
size);
|
||||
|
||||
if (descriptor->hasLabel())
|
||||
swapchain_->setLabel(descriptor->label());
|
||||
|
||||
// If we don't notify the host that something has changed it may never check
|
||||
// for the new cc::Layer.
|
||||
Host()->SetNeedsCompositingUpdate();
|
||||
|
@ -70,6 +70,7 @@ class GPUCanvasContext : public CanvasRenderingContext {
|
||||
int ExternallyAllocatedBufferCountPerPixel() final { return 1; }
|
||||
void Stop() final;
|
||||
cc::Layer* CcLayer() const final;
|
||||
void Reshape(int width, int height) override;
|
||||
|
||||
// OffscreenCanvas-specific methods
|
||||
bool PushFrame() final;
|
||||
@ -91,11 +92,20 @@ class GPUCanvasContext : public CanvasRenderingContext {
|
||||
GPUTexture* getCurrentTexture(ExceptionState&);
|
||||
|
||||
private:
|
||||
void ReconfigureSwapchain(gfx::Size size);
|
||||
|
||||
cc::PaintFlags::FilterQuality filter_quality_ =
|
||||
cc::PaintFlags::FilterQuality::kLow;
|
||||
Member<GPUSwapChain> swapchain_;
|
||||
Member<GPUDevice> configured_device_;
|
||||
WGPUTextureUsage usage_;
|
||||
WGPUTextureFormat format_;
|
||||
V8GPUCanvasCompositingAlphaMode::Enum alpha_mode_;
|
||||
|
||||
bool stopped_ = false;
|
||||
|
||||
// TODO(crbug.com/1326473): Remove after deprecation period.
|
||||
gfx::Size configured_size_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
Reference in New Issue
Block a user