Bug 1637972 - WebGPU handle canvas resize r=aosmond

we recreate the swapchain on the size change

Differential Revision: https://phabricator.services.mozilla.com/D113172
This commit is contained in:
Dzmitry Malyshau 2021-04-27 18:36:48 +00:00
Родитель 96461a9f97
Коммит 0fad36e113
5 изменённых файлов: 44 добавлений и 15 удалений

Просмотреть файл

@ -115,14 +115,34 @@ wr::ImageKey CanvasContext::CreateImageKey(
bool CanvasContext::UpdateWebRenderLocalCanvasData(
layers::WebRenderLocalCanvasData* aCanvasData) {
if (!mSwapChain || !mSwapChain->GetGpuBridge()) {
if (!mSwapChain || !mSwapChain->GetParent()) {
return false;
}
aCanvasData->mGpuBridge = mSwapChain->GetGpuBridge();
const auto size =
nsIntSize(AssertedCast<int>(mWidth), AssertedCast<int>(mHeight));
if (mSwapChain->mSize != size) {
const auto gfxFormat = mSwapChain->mGfxFormat;
dom::GPUSwapChainDescriptor desc;
desc.mFormat = static_cast<dom::GPUTextureFormat>(mSwapChain->mFormat);
desc.mUsage = mSwapChain->mUsage;
desc.mDevice = mSwapChain->GetParent();
mSwapChain->Destroy(mExternalImageId);
mExternalImageId =
layers::CompositorManagerChild::GetInstance()->GetNextExternalImageId();
dom::GPUExtent3DDict extent;
extent.mWidth = size.width;
extent.mHeight = size.height;
extent.mDepthOrArrayLayers = 1;
mSwapChain = new SwapChain(desc, extent, mExternalImageId, gfxFormat);
}
aCanvasData->mGpuBridge = mSwapChain->GetParent()->GetBridge().get();
aCanvasData->mGpuTextureId = mSwapChain->GetCurrentTexture()->mId;
aCanvasData->mExternalImageId = mExternalImageId;
aCanvasData->mFormat = mSwapChain->mFormat;
aCanvasData->mFormat = mSwapChain->mGfxFormat;
return true;
}

Просмотреть файл

@ -48,7 +48,7 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
bool UpdateWebRenderLocalCanvasData(
layers::WebRenderLocalCanvasData* aCanvasData);
const wr::ExternalImageId mExternalImageId;
wr::ExternalImageId mExternalImageId;
public: // nsICanvasRenderingContextInternal
int32_t GetWidth() override { return mWidth; }

Просмотреть файл

@ -19,7 +19,10 @@ SwapChain::SwapChain(const dom::GPUSwapChainDescriptor& aDesc,
wr::ExternalImageId aExternalImageId,
gfx::SurfaceFormat aFormat)
: ChildOf(aDesc.mDevice),
mFormat(aFormat),
mGfxFormat(aFormat),
mFormat(static_cast<uint8_t>(aDesc.mFormat)),
mUsage(aDesc.mUsage),
mSize(aExtent3D.mWidth, aExtent3D.mHeight),
mTexture(aDesc.mDevice->InitSwapChain(aDesc, aExtent3D, aExternalImageId,
aFormat)) {}
@ -31,9 +34,7 @@ void SwapChain::Cleanup() {
}
}
WebGPUChild* SwapChain::GetGpuBridge() const {
return mParent ? mParent->GetBridge().get() : nullptr;
}
RefPtr<Device> SwapChain::GetParent() const { return mParent; }
void SwapChain::Destroy(wr::ExternalImageId aExternalImageId) {
if (mValid && mParent && mParent->GetBridge()) {

Просмотреть файл

@ -29,10 +29,14 @@ class SwapChain final : public ObjectBase, public ChildOf<Device> {
const dom::GPUExtent3DDict& aExtent3D,
wr::ExternalImageId aExternalImageId, gfx::SurfaceFormat aFormat);
WebGPUChild* GetGpuBridge() const;
RefPtr<Device> GetParent() const;
void Destroy(wr::ExternalImageId aExternalImageId);
const gfx::SurfaceFormat mFormat;
const gfx::SurfaceFormat mGfxFormat;
const uint8_t
mFormat; // This is `dom::GPUTextureFormat` but without the includes
const uint32_t mUsage;
const nsIntSize mSize;
private:
virtual ~SwapChain();

Просмотреть файл

@ -525,11 +525,15 @@ static void PresentCallback(ffi::WGPUBufferMapAsyncStatus status,
const auto bufferSize = data->mRowCount * data->mSourcePitch;
const uint8_t* ptr = ffi::wgpu_server_buffer_get_mapped_range(
req->mContext, bufferId, 0, bufferSize);
uint8_t* dst = data->mTextureHost->GetBuffer();
for (uint32_t row = 0; row < data->mRowCount; ++row) {
memcpy(dst, ptr, data->mTargetPitch);
dst += data->mTargetPitch;
ptr += data->mSourcePitch;
if (data->mTextureHost) {
uint8_t* dst = data->mTextureHost->GetBuffer();
for (uint32_t row = 0; row < data->mRowCount; ++row) {
memcpy(dst, ptr, data->mTargetPitch);
dst += data->mTargetPitch;
ptr += data->mSourcePitch;
}
} else {
NS_WARNING("WebGPU present skipped: the swapchain is resized!");
}
wgpu_server_buffer_unmap(req->mContext, bufferId);
} else {