mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1753302 - Part 1. Integrate WebGPU with OffscreenCanvas plumbing. r=gfx-reviewers,jgilbert
Differential Revision: https://phabricator.services.mozilla.com/D141491
This commit is contained in:
parent
524448eb15
commit
3fe3f7ca98
@ -48,7 +48,6 @@ OffscreenCanvas::OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth,
|
||||
layers::TextureType aTextureType,
|
||||
OffscreenCanvasDisplayHelper* aDisplay)
|
||||
: DOMEventTargetHelper(aGlobal),
|
||||
mAttrDirty(false),
|
||||
mNeutered(false),
|
||||
mIsWriteOnly(false),
|
||||
mWidth(aWidth),
|
||||
|
@ -163,12 +163,10 @@ class OffscreenCanvas final : public DOMEventTargetHelper,
|
||||
nsCOMPtr<nsIGlobalObject>&& aGlobal, Promise* aPromise);
|
||||
|
||||
void CanvasAttrChanged() {
|
||||
mAttrDirty = true;
|
||||
ErrorResult dummy;
|
||||
UpdateContext(nullptr, JS::NullHandleValue, dummy);
|
||||
}
|
||||
|
||||
bool mAttrDirty;
|
||||
bool mNeutered;
|
||||
bool mIsWriteOnly;
|
||||
|
||||
|
@ -45,11 +45,21 @@ RefPtr<layers::ImageContainer> OffscreenCanvasDisplayHelper::GetImageContainer()
|
||||
return mImageContainer;
|
||||
}
|
||||
|
||||
layers::CompositableHandle OffscreenCanvasDisplayHelper::GetCompositableHandle()
|
||||
const {
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mData.mHandle;
|
||||
}
|
||||
|
||||
void OffscreenCanvasDisplayHelper::UpdateContext(
|
||||
CanvasContextType aType, const Maybe<int32_t>& aChildId) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
mImageContainer =
|
||||
MakeRefPtr<layers::ImageContainer>(layers::ImageContainer::ASYNCHRONOUS);
|
||||
|
||||
if (aType != CanvasContextType::WebGPU) {
|
||||
mImageContainer = MakeRefPtr<layers::ImageContainer>(
|
||||
layers::ImageContainer::ASYNCHRONOUS);
|
||||
}
|
||||
|
||||
mType = aType;
|
||||
mContextChildId = aChildId;
|
||||
|
||||
@ -82,6 +92,16 @@ bool OffscreenCanvasDisplayHelper::CommitFrameToCompositor(
|
||||
MaybeQueueInvalidateElement();
|
||||
}
|
||||
|
||||
if (mData.mHandle) {
|
||||
// No need to update the ImageContainer as the presentation itself is
|
||||
// handled in the compositor process.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mImageContainer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mData.mIsOpaque) {
|
||||
flags |= layers::TextureFlags::IS_OPAQUE;
|
||||
format = gfx::SurfaceFormat::B8G8R8X8;
|
||||
|
@ -28,6 +28,7 @@ struct OffscreenCanvasDisplayData final {
|
||||
bool mIsOpaque = true;
|
||||
bool mIsAlphaPremult = true;
|
||||
mozilla::gl::OriginPos mOriginPos = gl::OriginPos::TopLeft;
|
||||
mozilla::layers::CompositableHandle mHandle;
|
||||
};
|
||||
|
||||
class OffscreenCanvasDisplayHelper final {
|
||||
@ -41,6 +42,8 @@ class OffscreenCanvasDisplayHelper final {
|
||||
|
||||
RefPtr<layers::ImageContainer> GetImageContainer() const;
|
||||
|
||||
layers::CompositableHandle GetCompositableHandle() const;
|
||||
|
||||
void UpdateContext(CanvasContextType aType, const Maybe<int32_t>& aChildId);
|
||||
|
||||
bool CommitFrameToCompositor(nsICanvasRenderingContextInternal* aContext,
|
||||
|
@ -1478,4 +1478,11 @@ webgpu::CanvasContext* HTMLCanvasElement::GetWebGPUContext() {
|
||||
return static_cast<webgpu::CanvasContext*>(GetCurrentContext());
|
||||
}
|
||||
|
||||
CompositableHandle HTMLCanvasElement::GetCompositableHandle() const {
|
||||
if (mOffscreenDisplay) {
|
||||
return mOffscreenDisplay->GetCompositableHandle();
|
||||
}
|
||||
return CompositableHandle();
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
@ -347,6 +347,8 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
|
||||
|
||||
layers::ImageContainer* GetImageContainer() const { return mImageContainer; }
|
||||
|
||||
layers::CompositableHandle GetCompositableHandle() const;
|
||||
|
||||
protected:
|
||||
bool mResetLayer;
|
||||
bool mMaybeModified; // we fetched the context, so we may have written to the
|
||||
|
@ -73,7 +73,14 @@ void CanvasContext::Configure(const dom::GPUCanvasConfiguration& aDesc) {
|
||||
// Force a new frame to be built, which will execute the
|
||||
// `CanvasContextType::WebGPU` switch case in `CreateWebRenderCommands` and
|
||||
// populate the WR user data.
|
||||
mCanvasElement->InvalidateCanvas();
|
||||
if (mCanvasElement) {
|
||||
mCanvasElement->InvalidateCanvas();
|
||||
} else if (mOffscreenCanvas) {
|
||||
dom::OffscreenCanvasDisplayData data;
|
||||
data.mSize = {mWidth, mHeight};
|
||||
data.mHandle = mHandle;
|
||||
mOffscreenCanvas->UpdateDisplayData(data);
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasContext::Unconfigure() {
|
||||
|
@ -108,27 +108,35 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem {
|
||||
element->HandlePrintCallback(mFrame->PresContext());
|
||||
|
||||
if (element->IsOffscreen()) {
|
||||
// If we are offscreen, then we display via an ImageContainer which is
|
||||
// updated asynchronously, likely from a worker thread. There is nothing
|
||||
// to paint until the owner attaches it.
|
||||
// If we are offscreen, then we either display via an ImageContainer
|
||||
// which is updated asynchronously, likely from a worker thread, or a
|
||||
// CompositableHandle managed inside the compositor process. There is
|
||||
// nothing to paint until the owner attaches it.
|
||||
|
||||
nsHTMLCanvasFrame* canvasFrame = static_cast<nsHTMLCanvasFrame*>(mFrame);
|
||||
nsIntSize canvasSizeInPx = canvasFrame->GetCanvasSize();
|
||||
IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx);
|
||||
AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx);
|
||||
nsRect area = mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame();
|
||||
nsRect dest = nsLayoutUtils::ComputeObjectDestRect(
|
||||
area, intrinsicSize, intrinsicRatio, mFrame->StylePosition());
|
||||
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
|
||||
dest, mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
|
||||
RefPtr<ImageContainer> container = element->GetImageContainer();
|
||||
if (container) {
|
||||
nsHTMLCanvasFrame* canvasFrame =
|
||||
static_cast<nsHTMLCanvasFrame*>(mFrame);
|
||||
nsIntSize canvasSizeInPx = canvasFrame->GetCanvasSize();
|
||||
IntrinsicSize intrinsicSize =
|
||||
IntrinsicSizeFromCanvasSize(canvasSizeInPx);
|
||||
AspectRatio intrinsicRatio =
|
||||
IntrinsicRatioFromCanvasSize(canvasSizeInPx);
|
||||
nsRect area =
|
||||
mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame();
|
||||
nsRect dest = nsLayoutUtils::ComputeObjectDestRect(
|
||||
area, intrinsicSize, intrinsicRatio, mFrame->StylePosition());
|
||||
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
|
||||
dest, mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
aManager->CommandBuilder().PushImage(this, container, aBuilder,
|
||||
aResources, aSc, bounds, bounds);
|
||||
return true;
|
||||
}
|
||||
|
||||
CompositableHandle handle = element->GetCompositableHandle();
|
||||
if (handle) {
|
||||
aManager->CommandBuilder().PushInProcessImage(this, handle, aBuilder,
|
||||
aResources, aSc, bounds);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user