зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
96461a9f97
Коммит
0fad36e113
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче