forked from mirrors/gecko-dev
Bug 1805209 - Use RemoteTexture for WebGPU r=gfx-reviewers,lsalzman
WebGPU uses CompositableInProcessManager to push TextureHost directly from WebGPUParent to WebRender. But CompositableInProcessManager plumbing has a problem and caused Bug 1805209. gecko already has a similar mechanism, called RemoteTextureMap. It is used in oop WebGL. If WebGPU uses RemoteTextureMap instead of CompositableInProcessManager, both WebGPU and oop WebGL use same mechanism. WebGPUParent pushes a new texture to RemoteTextureMap. The RemoteTextureMap notifies the pushed texture to WebRenderImageHost. Before the change, only one TextureHost is used for one swap chain. With the change, multiple TextureHosts are used for one swap chain with recycling. The changes are followings. - Use RemoteTextureMap instead of CompositableInProcessManager. - Use RemoteTextureOwnerId instead of CompositableHandle. - Use WebRenderCanvasData instead of WebRenderInProcessImageData. - Add remote texture pushed callback functionality to RemoteTextureMap. With it, RemoteTextureMap notifies a new pushed remote texture to WebRenderImageHost. - Remove CompositableInProcessManager. Differential Revision: https://phabricator.services.mozilla.com/D164890
This commit is contained in:
parent
8f1aac156b
commit
954c16acec
49 changed files with 560 additions and 559 deletions
|
|
@ -45,19 +45,10 @@ 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) {
|
||||
RefPtr<layers::ImageContainer> imageContainer;
|
||||
if (aType != CanvasContextType::WebGPU) {
|
||||
imageContainer = MakeRefPtr<layers::ImageContainer>(
|
||||
layers::ImageContainer::ASYNCHRONOUS);
|
||||
}
|
||||
RefPtr<layers::ImageContainer> imageContainer =
|
||||
MakeRefPtr<layers::ImageContainer>(layers::ImageContainer::ASYNCHRONOUS);
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
|
|
@ -94,7 +85,7 @@ bool OffscreenCanvasDisplayHelper::CommitFrameToCompositor(
|
|||
MaybeQueueInvalidateElement();
|
||||
}
|
||||
|
||||
if (mData.mHandle) {
|
||||
if (mData.mOwnerId.isSome()) {
|
||||
// No need to update the ImageContainer as the presentation itself is
|
||||
// handled in the compositor process.
|
||||
return true;
|
||||
|
|
@ -279,14 +270,14 @@ OffscreenCanvasDisplayHelper::GetSurfaceSnapshot() {
|
|||
Maybe<int32_t> childId;
|
||||
HTMLCanvasElement* canvasElement;
|
||||
RefPtr<gfx::SourceSurface> surface;
|
||||
layers::CompositableHandle handle;
|
||||
Maybe<layers::RemoteTextureOwnerId> ownerId;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
hasAlpha = !mData.mIsOpaque;
|
||||
isAlphaPremult = mData.mIsAlphaPremult;
|
||||
originPos = mData.mOriginPos;
|
||||
handle = mData.mHandle;
|
||||
ownerId = mData.mOwnerId;
|
||||
managerId = mContextManagerId;
|
||||
childId = mContextChildId;
|
||||
canvasElement = mCanvasElement;
|
||||
|
|
@ -340,7 +331,7 @@ OffscreenCanvasDisplayHelper::GetSurfaceSnapshot() {
|
|||
// We don't have a usable surface, and the context lives in the compositor
|
||||
// process.
|
||||
return gfx::CanvasManagerChild::Get()->GetSnapshot(
|
||||
managerId.value(), childId.value(), handle,
|
||||
managerId.value(), childId.value(), ownerId,
|
||||
hasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
|
||||
hasAlpha && !isAlphaPremult, originPos == gl::OriginPos::BottomLeft);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ struct OffscreenCanvasDisplayData final {
|
|||
bool mIsOpaque = true;
|
||||
bool mIsAlphaPremult = true;
|
||||
mozilla::gl::OriginPos mOriginPos = gl::OriginPos::TopLeft;
|
||||
mozilla::layers::CompositableHandle mHandle;
|
||||
Maybe<layers::RemoteTextureOwnerId> mOwnerId;
|
||||
};
|
||||
|
||||
class OffscreenCanvasDisplayHelper final {
|
||||
|
|
@ -41,8 +41,6 @@ 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,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ include protocol PCanvasManager;
|
|||
include "mozilla/layers/LayersMessageUtils.h";
|
||||
|
||||
[MoveOnly] using class mozilla::ipc::BigBuffer from "mozilla/ipc/BigBuffer.h";
|
||||
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
|
||||
using mozilla::layers::SurfaceDescriptor from "mozilla/layers/LayersTypes.h";
|
||||
using std::string from "string";
|
||||
using mozilla::uvec2 from "mozilla/dom/WebGLIpdl.h";
|
||||
|
|
|
|||
|
|
@ -1122,7 +1122,9 @@ bool WebGLContext::PushRemoteTexture(WebGLFramebuffer* fb,
|
|||
};
|
||||
|
||||
swapChain.SetDestroyedCallback(destroyedCallback);
|
||||
mRemoteTextureOwner->RegisterTextureOwner(ownerId);
|
||||
mRemoteTextureOwner->RegisterTextureOwner(
|
||||
ownerId,
|
||||
/* aIsSyncMode */ gfx::gfxVars::WebglOopAsyncPresentForceSync());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(fb || surf);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ class PresShell;
|
|||
class WebGLFramebufferJS;
|
||||
namespace layers {
|
||||
class CanvasRenderer;
|
||||
class CompositableHandle;
|
||||
class Layer;
|
||||
class Image;
|
||||
class LayerManager;
|
||||
|
|
|
|||
|
|
@ -1360,11 +1360,4 @@ webgpu::CanvasContext* HTMLCanvasElement::GetWebGPUContext() {
|
|||
return static_cast<webgpu::CanvasContext*>(GetCurrentContext());
|
||||
}
|
||||
|
||||
CompositableHandle HTMLCanvasElement::GetCompositableHandle() const {
|
||||
if (mOffscreenDisplay) {
|
||||
return mOffscreenDisplay->GetCompositableHandle();
|
||||
}
|
||||
return CompositableHandle();
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
|||
|
|
@ -343,8 +343,6 @@ 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
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@
|
|||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/gfx/CanvasManagerChild.h"
|
||||
#include "mozilla/layers/CanvasRenderer.h"
|
||||
#include "mozilla/layers/CompositableInProcessManager.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
#include "mozilla/layers/RenderRootStateManager.h"
|
||||
#include "mozilla/layers/WebRenderCanvasRenderer.h"
|
||||
#include "ipc/WebGPUChild.h"
|
||||
|
||||
namespace mozilla::webgpu {
|
||||
|
|
@ -65,9 +65,9 @@ void CanvasContext::Configure(const dom::GPUCanvasConfiguration& aDesc) {
|
|||
}
|
||||
|
||||
gfx::IntSize actualSize(mWidth, mHeight);
|
||||
mHandle = layers::CompositableInProcessManager::GetNextHandle();
|
||||
mTexture =
|
||||
aDesc.mDevice->InitSwapChain(aDesc, mHandle, mGfxFormat, &actualSize);
|
||||
mRemoteTextureOwnerId = Some(layers::RemoteTextureOwnerId::GetNext());
|
||||
mTexture = aDesc.mDevice->InitSwapChain(aDesc, *mRemoteTextureOwnerId,
|
||||
mGfxFormat, &actualSize);
|
||||
if (!mTexture) {
|
||||
Unconfigure();
|
||||
return;
|
||||
|
|
@ -77,25 +77,14 @@ void CanvasContext::Configure(const dom::GPUCanvasConfiguration& aDesc) {
|
|||
mBridge = aDesc.mDevice->GetBridge();
|
||||
mGfxSize = actualSize;
|
||||
|
||||
// Force a new frame to be built, which will execute the
|
||||
// `CanvasContextType::WebGPU` switch case in `CreateWebRenderCommands` and
|
||||
// populate the WR user data.
|
||||
if (mCanvasElement) {
|
||||
mCanvasElement->InvalidateCanvas();
|
||||
} else if (mOffscreenCanvas) {
|
||||
dom::OffscreenCanvasDisplayData data;
|
||||
data.mSize = {mWidth, mHeight};
|
||||
data.mIsOpaque = false;
|
||||
data.mHandle = mHandle;
|
||||
mOffscreenCanvas->UpdateDisplayData(data);
|
||||
}
|
||||
ForceNewFrame();
|
||||
}
|
||||
|
||||
void CanvasContext::Unconfigure() {
|
||||
if (mBridge && mBridge->IsOpen() && mHandle) {
|
||||
mBridge->SendSwapChainDestroy(mHandle);
|
||||
if (mBridge && mBridge->IsOpen() && mRemoteTextureOwnerId.isSome()) {
|
||||
mBridge->SendSwapChainDestroy(*mRemoteTextureOwnerId);
|
||||
}
|
||||
mHandle = layers::CompositableHandle();
|
||||
mRemoteTextureOwnerId = Nothing();
|
||||
mBridge = nullptr;
|
||||
mTexture = nullptr;
|
||||
mGfxFormat = gfx::SurfaceFormat::UNKNOWN;
|
||||
|
|
@ -126,16 +115,37 @@ void CanvasContext::MaybeQueueSwapChainPresent() {
|
|||
|
||||
void CanvasContext::SwapChainPresent() {
|
||||
mPendingSwapChainPresent = false;
|
||||
if (mBridge && mBridge->IsOpen() && mHandle && mTexture) {
|
||||
mBridge->SwapChainPresent(mHandle, mTexture->mId);
|
||||
if (!mBridge || !mBridge->IsOpen() || mRemoteTextureOwnerId.isNothing() ||
|
||||
!mTexture) {
|
||||
return;
|
||||
}
|
||||
mLastRemoteTextureId = Some(layers::RemoteTextureId::GetNext());
|
||||
mBridge->SwapChainPresent(mTexture->mId, *mLastRemoteTextureId,
|
||||
*mRemoteTextureOwnerId);
|
||||
}
|
||||
|
||||
bool CanvasContext::UpdateWebRenderCanvasData(
|
||||
mozilla::nsDisplayListBuilder* aBuilder, WebRenderCanvasData* aCanvasData) {
|
||||
auto* renderer = aCanvasData->GetCanvasRenderer();
|
||||
|
||||
if (renderer && mRemoteTextureOwnerId.isSome() &&
|
||||
renderer->GetRemoteTextureOwnerIdOfPushCallback() ==
|
||||
mRemoteTextureOwnerId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
renderer = aCanvasData->CreateCanvasRenderer();
|
||||
if (!InitializeCanvasRenderer(aBuilder, renderer)) {
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanvasContext::InitializeCanvasRenderer(
|
||||
nsDisplayListBuilder* aBuilder, layers::CanvasRenderer* aRenderer) {
|
||||
// This path is only used for rendering when we use the fallback Paint path,
|
||||
// used by reftest-snapshot, printing and Firefox Screenshot.
|
||||
if (!mHandle) {
|
||||
if (mRemoteTextureOwnerId.isNothing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -143,6 +153,7 @@ bool CanvasContext::InitializeCanvasRenderer(
|
|||
data.mContext = this;
|
||||
data.mSize = mGfxSize;
|
||||
data.mIsOpaque = false;
|
||||
data.mRemoteTextureOwnerIdOfPushCallback = mRemoteTextureOwnerId;
|
||||
|
||||
aRenderer->Initialize(data);
|
||||
aRenderer->SetDirty();
|
||||
|
|
@ -187,12 +198,33 @@ already_AddRefed<mozilla::gfx::SourceSurface> CanvasContext::GetSurfaceSnapshot(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mBridge || !mBridge->IsOpen() || !mHandle) {
|
||||
if (!mBridge || !mBridge->IsOpen() || mRemoteTextureOwnerId.isNothing()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return cm->GetSnapshot(cm->Id(), mBridge->Id(), mHandle, mGfxFormat,
|
||||
/* aPremultiply */ false, /* aYFlip */ false);
|
||||
MOZ_ASSERT(mRemoteTextureOwnerId.isSome());
|
||||
return cm->GetSnapshot(cm->Id(), mBridge->Id(), mRemoteTextureOwnerId,
|
||||
mGfxFormat, /* aPremultiply */ false,
|
||||
/* aYFlip */ false);
|
||||
}
|
||||
|
||||
void CanvasContext::ForceNewFrame() {
|
||||
if (!mCanvasElement && !mOffscreenCanvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force a new frame to be built, which will execute the
|
||||
// `CanvasContextType::WebGPU` switch case in `CreateWebRenderCommands` and
|
||||
// populate the WR user data.
|
||||
if (mCanvasElement) {
|
||||
mCanvasElement->InvalidateCanvas();
|
||||
} else if (mOffscreenCanvas) {
|
||||
dom::OffscreenCanvasDisplayData data;
|
||||
data.mSize = {mWidth, mHeight};
|
||||
data.mIsOpaque = false;
|
||||
data.mOwnerId = mRemoteTextureOwnerId;
|
||||
mOffscreenCanvas->UpdateDisplayData(data);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla::webgpu
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
|
|||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
layers::CompositableHandle mHandle;
|
||||
|
||||
public: // nsICanvasRenderingContextInternal
|
||||
int32_t GetWidth() override { return mWidth; }
|
||||
int32_t GetHeight() override { return mHeight; }
|
||||
|
|
@ -54,6 +52,9 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool UpdateWebRenderCanvasData(mozilla::nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) override;
|
||||
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
layers::CanvasRenderer* aRenderer) override;
|
||||
mozilla::UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aFormat) override;
|
||||
|
|
@ -87,6 +88,7 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
|
|||
RefPtr<Texture> GetCurrentTexture(ErrorResult& aRv);
|
||||
void MaybeQueueSwapChainPresent();
|
||||
void SwapChainPresent();
|
||||
void ForceNewFrame();
|
||||
|
||||
private:
|
||||
uint32_t mWidth = 0, mHeight = 0;
|
||||
|
|
@ -96,6 +98,9 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
|
|||
RefPtr<Texture> mTexture;
|
||||
gfx::SurfaceFormat mGfxFormat = gfx::SurfaceFormat::R8G8B8A8;
|
||||
gfx::IntSize mGfxSize;
|
||||
|
||||
Maybe<layers::RemoteTextureId> mLastRemoteTextureId;
|
||||
Maybe<layers::RemoteTextureOwnerId> mRemoteTextureOwnerId;
|
||||
};
|
||||
|
||||
} // namespace webgpu
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ already_AddRefed<dom::Promise> Device::CreateRenderPipelineAsync(
|
|||
|
||||
already_AddRefed<Texture> Device::InitSwapChain(
|
||||
const dom::GPUCanvasConfiguration& aDesc,
|
||||
const layers::CompositableHandle& aHandle, gfx::SurfaceFormat aFormat,
|
||||
const layers::RemoteTextureOwnerId aOwnerId, gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize* aCanvasSize) {
|
||||
if (!mBridge->CanSend()) {
|
||||
return nullptr;
|
||||
|
|
@ -327,7 +327,7 @@ already_AddRefed<Texture> Device::InitSwapChain(
|
|||
const layers::RGBDescriptor rgbDesc(size, aFormat);
|
||||
// buffer count doesn't matter much, will be created on demand
|
||||
const size_t maxBufferCount = 10;
|
||||
mBridge->DeviceCreateSwapChain(mId, rgbDesc, maxBufferCount, aHandle);
|
||||
mBridge->DeviceCreateSwapChain(mId, rgbDesc, maxBufferCount, aOwnerId);
|
||||
|
||||
dom::GPUTextureDescriptor desc;
|
||||
desc.mDimension = dom::GPUTextureDimension::_2d;
|
||||
|
|
|
|||
|
|
@ -53,9 +53,6 @@ namespace ipc {
|
|||
enum class ResponseRejectReason;
|
||||
class Shmem;
|
||||
} // namespace ipc
|
||||
namespace layers {
|
||||
class CompositableHandle;
|
||||
} // namespace layers
|
||||
|
||||
namespace webgpu {
|
||||
namespace ffi {
|
||||
|
|
@ -102,7 +99,7 @@ class Device final : public DOMEventTargetHelper, public SupportsWeakPtr {
|
|||
const ipc::Shmem& aShmem);
|
||||
already_AddRefed<Texture> InitSwapChain(
|
||||
const dom::GPUCanvasConfiguration& aDesc,
|
||||
const layers::CompositableHandle& aHandle, gfx::SurfaceFormat aFormat,
|
||||
const layers::RemoteTextureOwnerId aOwnerId, gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize* aDefaultSize);
|
||||
bool CheckNewWarning(const nsACString& aMessage);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
using layers::RGBDescriptor from "mozilla/layers/LayersSurfaces.h";
|
||||
using layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
|
||||
using layers::RemoteTextureId from "mozilla/layers/LayersTypes.h";
|
||||
using layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h";
|
||||
using RawId from "mozilla/webgpu/WebGPUTypes.h";
|
||||
using dom::GPURequestAdapterOptions from "mozilla/dom/WebGPUBinding.h";
|
||||
using dom::GPUCommandBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
|
||||
|
|
@ -71,9 +72,9 @@ parent:
|
|||
async ComputePipelineDestroy(RawId selfId);
|
||||
async RenderPipelineDestroy(RawId selfId);
|
||||
async ImplicitLayoutDestroy(RawId implicitPlId, RawId[] implicitBglIds);
|
||||
async DeviceCreateSwapChain(RawId selfId, RawId queueId, RGBDescriptor desc, RawId[] bufferIds, CompositableHandle handle);
|
||||
async SwapChainPresent(CompositableHandle handle, RawId textureId, RawId commandEncoderId);
|
||||
async SwapChainDestroy(CompositableHandle handle);
|
||||
async DeviceCreateSwapChain(RawId selfId, RawId queueId, RGBDescriptor desc, RawId[] bufferIds, RemoteTextureOwnerId ownerId);
|
||||
async SwapChainPresent(RawId textureId, RawId commandEncoderId, RemoteTextureId remoteTextureId, RemoteTextureOwnerId remoteTextureOwnerId);
|
||||
async SwapChainDestroy(RemoteTextureOwnerId ownerId);
|
||||
|
||||
async DevicePushErrorScope(RawId selfId);
|
||||
async DevicePopErrorScope(RawId selfId) returns (MaybeScopedError maybeError);
|
||||
|
|
|
|||
|
|
@ -1013,22 +1013,23 @@ ipc::IPCResult WebGPUChild::RecvDropAction(const ipc::ByteBuf& aByteBuf) {
|
|||
|
||||
void WebGPUChild::DeviceCreateSwapChain(
|
||||
RawId aSelfId, const RGBDescriptor& aRgbDesc, size_t maxBufferCount,
|
||||
const layers::CompositableHandle& aHandle) {
|
||||
const layers::RemoteTextureOwnerId& aOwnerId) {
|
||||
RawId queueId = aSelfId; // TODO: multiple queues
|
||||
nsTArray<RawId> bufferIds(maxBufferCount);
|
||||
for (size_t i = 0; i < maxBufferCount; ++i) {
|
||||
bufferIds.AppendElement(
|
||||
ffi::wgpu_client_make_buffer_id(mClient.get(), aSelfId));
|
||||
}
|
||||
SendDeviceCreateSwapChain(aSelfId, queueId, aRgbDesc, bufferIds, aHandle);
|
||||
SendDeviceCreateSwapChain(aSelfId, queueId, aRgbDesc, bufferIds, aOwnerId);
|
||||
}
|
||||
|
||||
void WebGPUChild::SwapChainPresent(const layers::CompositableHandle& aHandle,
|
||||
RawId aTextureId) {
|
||||
void WebGPUChild::SwapChainPresent(RawId aTextureId,
|
||||
const RemoteTextureId& aRemoteTextureId,
|
||||
const RemoteTextureOwnerId& aOwnerId) {
|
||||
// Hack: the function expects `DeviceId`, but it only uses it for `backend()`
|
||||
// selection.
|
||||
RawId encoderId = ffi::wgpu_client_make_encoder_id(mClient.get(), aTextureId);
|
||||
SendSwapChainPresent(aHandle, aTextureId, encoderId);
|
||||
SendSwapChainPresent(aTextureId, encoderId, aRemoteTextureId, aOwnerId);
|
||||
}
|
||||
|
||||
void WebGPUChild::RegisterDevice(Device* const aDevice) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ namespace dom {
|
|||
struct GPURequestAdapterOptions;
|
||||
} // namespace dom
|
||||
namespace layers {
|
||||
class CompositableHandle;
|
||||
class CompositorBridgeChild;
|
||||
} // namespace layers
|
||||
namespace webgpu {
|
||||
|
|
@ -105,9 +104,10 @@ class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
|||
|
||||
void DeviceCreateSwapChain(RawId aSelfId, const RGBDescriptor& aRgbDesc,
|
||||
size_t maxBufferCount,
|
||||
const layers::CompositableHandle& aHandle);
|
||||
void SwapChainPresent(const layers::CompositableHandle& aHandle,
|
||||
RawId aTextureId);
|
||||
const layers::RemoteTextureOwnerId& aOwnerId);
|
||||
void SwapChainPresent(RawId aTextureId,
|
||||
const RemoteTextureId& aRemoteTextureId,
|
||||
const RemoteTextureOwnerId& aOwnerId);
|
||||
|
||||
void RegisterDevice(Device* const aDevice);
|
||||
void UnregisterDevice(RawId aId);
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
#include "WebGPUParent.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/webgpu/ffi/wgpu.h"
|
||||
#include "mozilla/layers/CompositableInProcessManager.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/RemoteTextureMap.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/WebRenderImageHost.h"
|
||||
#include "mozilla/layers/WebRenderTextureHost.h"
|
||||
|
|
@ -68,11 +68,8 @@ class PresentationData {
|
|||
public:
|
||||
RawId mDeviceId = 0;
|
||||
RawId mQueueId = 0;
|
||||
RefPtr<layers::WebRenderImageHost> mImageHost;
|
||||
RefPtr<layers::MemoryTextureHost> mTextureHost;
|
||||
layers::RGBDescriptor mDesc;
|
||||
uint32_t mSourcePitch = 0;
|
||||
uint32_t mTargetPitch = 0;
|
||||
uint32_t mRowCount = 0;
|
||||
int32_t mNextFrameID = 1;
|
||||
std::vector<RawId> mUnassignedBufferIds;
|
||||
std::vector<RawId> mAvailableBufferIds;
|
||||
|
|
@ -80,17 +77,12 @@ class PresentationData {
|
|||
Mutex mBuffersLock MOZ_UNANNOTATED;
|
||||
|
||||
PresentationData(RawId aDeviceId, RawId aQueueId,
|
||||
already_AddRefed<layers::WebRenderImageHost> aImageHost,
|
||||
already_AddRefed<layers::MemoryTextureHost> aTextureHost,
|
||||
uint32_t aSourcePitch, uint32_t aTargetPitch, uint32_t aRows,
|
||||
const layers::RGBDescriptor& aDesc, uint32_t aSourcePitch,
|
||||
const nsTArray<RawId>& aBufferIds)
|
||||
: mDeviceId(aDeviceId),
|
||||
mQueueId(aQueueId),
|
||||
mImageHost(aImageHost),
|
||||
mTextureHost(aTextureHost),
|
||||
mDesc(aDesc),
|
||||
mSourcePitch(aSourcePitch),
|
||||
mTargetPitch(aTargetPitch),
|
||||
mRowCount(aRows),
|
||||
mBuffersLock("WebGPU presentation buffers") {
|
||||
MOZ_COUNT_CTOR(PresentationData);
|
||||
|
||||
|
|
@ -682,7 +674,8 @@ ipc::IPCResult WebGPUParent::RecvImplicitLayoutDestroy(
|
|||
|
||||
ipc::IPCResult WebGPUParent::RecvDeviceCreateSwapChain(
|
||||
RawId aDeviceId, RawId aQueueId, const RGBDescriptor& aDesc,
|
||||
const nsTArray<RawId>& aBufferIds, const CompositableHandle& aHandle) {
|
||||
const nsTArray<RawId>& aBufferIds,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId) {
|
||||
switch (aDesc.format()) {
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
|
|
@ -703,12 +696,6 @@ ipc::IPCResult WebGPUParent::RecvDeviceCreateSwapChain(
|
|||
|
||||
const uint32_t bufferStride =
|
||||
bufferStrideWithMask.value() & ~kBufferAlignmentMask;
|
||||
// GetRGBStride does its own size validation and returns 0 if invalid.
|
||||
const auto textureStride = layers::ImageDataSerializer::GetRGBStride(aDesc);
|
||||
if (textureStride <= 0) {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid texture stride!");
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
const auto rows = CheckedInt<uint32_t>(aDesc.size().height);
|
||||
if (!rows.isValid()) {
|
||||
|
|
@ -716,38 +703,16 @@ ipc::IPCResult WebGPUParent::RecvDeviceCreateSwapChain(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
const auto wholeBufferSize = rows * bufferStride;
|
||||
const auto wholeTextureSize = rows * textureStride;
|
||||
if (!wholeBufferSize.isValid() || !wholeTextureSize.isValid()) {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid total buffer/texture size!");
|
||||
return IPC_OK();
|
||||
if (!mRemoteTextureOwner) {
|
||||
mRemoteTextureOwner =
|
||||
MakeRefPtr<layers::RemoteTextureOwnerClient>(OtherPid());
|
||||
}
|
||||
// RemoteTextureMap::GetRemoteTextureForDisplayList() works synchronously.
|
||||
mRemoteTextureOwner->RegisterTextureOwner(aOwnerId, /* aIsSyncMode */ true);
|
||||
|
||||
auto* textureHostData = new (fallible) uint8_t[wholeTextureSize.value()];
|
||||
if (NS_WARN_IF(!textureHostData)) {
|
||||
ReportError(
|
||||
aDeviceId,
|
||||
"Error in Device::create_swapchain: failed to allocate texture buffer"_ns);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
layers::TextureInfo texInfo(layers::CompositableType::IMAGE);
|
||||
layers::TextureFlags texFlags = layers::TextureFlags::NO_FLAGS;
|
||||
wr::ExternalImageId externalId =
|
||||
layers::CompositableInProcessManager::GetNextExternalImageId();
|
||||
|
||||
RefPtr<layers::WebRenderImageHost> imageHost =
|
||||
layers::CompositableInProcessManager::Add(aHandle, OtherPid(), texInfo);
|
||||
|
||||
auto textureHost =
|
||||
MakeRefPtr<layers::MemoryTextureHost>(textureHostData, aDesc, texFlags);
|
||||
textureHost->DisableExternalTextures();
|
||||
textureHost->EnsureRenderTexture(Some(externalId));
|
||||
|
||||
auto data = MakeRefPtr<PresentationData>(
|
||||
aDeviceId, aQueueId, imageHost.forget(), textureHost.forget(),
|
||||
bufferStride, textureStride, rows.value(), aBufferIds);
|
||||
if (!mCanvasMap.insert({aHandle.Value(), data}).second) {
|
||||
auto data = MakeRefPtr<PresentationData>(aDeviceId, aQueueId, aDesc,
|
||||
bufferStride, aBufferIds);
|
||||
if (!mCanvasMap.emplace(aOwnerId, data).second) {
|
||||
NS_ERROR("External image is already registered as WebGPU canvas!");
|
||||
}
|
||||
return IPC_OK();
|
||||
|
|
@ -789,13 +754,28 @@ ipc::IPCResult WebGPUParent::RecvDeviceCreateShaderModule(
|
|||
}
|
||||
|
||||
struct PresentRequest {
|
||||
PresentRequest(const ffi::WGPUGlobal* aContext,
|
||||
RefPtr<PresentationData>& aData,
|
||||
RefPtr<layers::RemoteTextureOwnerClient>& aRemoteTextureOwner,
|
||||
const layers::RemoteTextureId aTextureId,
|
||||
const layers::RemoteTextureOwnerId aOwnerId)
|
||||
: mContext(aContext),
|
||||
mData(aData),
|
||||
mRemoteTextureOwner(aRemoteTextureOwner),
|
||||
mTextureId(aTextureId),
|
||||
mOwnerId(aOwnerId) {}
|
||||
|
||||
const ffi::WGPUGlobal* mContext;
|
||||
RefPtr<PresentationData> mData;
|
||||
RefPtr<layers::RemoteTextureOwnerClient> mRemoteTextureOwner;
|
||||
const layers::RemoteTextureId mTextureId;
|
||||
const layers::RemoteTextureOwnerId mOwnerId;
|
||||
};
|
||||
|
||||
static void PresentCallback(ffi::WGPUBufferMapAsyncStatus status,
|
||||
uint8_t* userdata) {
|
||||
auto* req = reinterpret_cast<PresentRequest*>(userdata);
|
||||
UniquePtr<PresentRequest> req(reinterpret_cast<PresentRequest*>(userdata));
|
||||
|
||||
PresentationData* data = req->mData.get();
|
||||
// get the buffer ID
|
||||
RawId bufferId;
|
||||
|
|
@ -810,44 +790,29 @@ static void PresentCallback(ffi::WGPUBufferMapAsyncStatus status,
|
|||
("PresentCallback for buffer %" PRIu64 " status=%d\n", bufferId, status));
|
||||
// copy the data
|
||||
if (status == ffi::WGPUBufferMapAsyncStatus_Success) {
|
||||
const auto bufferSize = data->mRowCount * data->mSourcePitch;
|
||||
const auto bufferSize = data->mDesc.size().height * data->mSourcePitch;
|
||||
const auto mapped = ffi::wgpu_server_buffer_get_mapped_range(
|
||||
req->mContext, bufferId, 0, bufferSize);
|
||||
MOZ_ASSERT(mapped.length >= bufferSize);
|
||||
if (data->mTextureHost) {
|
||||
auto textureData =
|
||||
req->mRemoteTextureOwner->CreateOrRecycleBufferTextureData(
|
||||
req->mOwnerId, data->mDesc.size(), data->mDesc.format());
|
||||
if (!textureData) {
|
||||
gfxCriticalNoteOnce << "Failed to allocate BufferTextureData";
|
||||
return;
|
||||
}
|
||||
layers::MappedTextureData mappedData;
|
||||
if (textureData && textureData->BorrowMappedData(mappedData)) {
|
||||
uint8_t* src = mapped.ptr;
|
||||
uint8_t* dst = data->mTextureHost->GetBuffer();
|
||||
for (uint32_t row = 0; row < data->mRowCount; ++row) {
|
||||
memcpy(dst, src, data->mTargetPitch);
|
||||
dst += data->mTargetPitch;
|
||||
uint8_t* dst = mappedData.data;
|
||||
for (auto row = 0; row < data->mDesc.size().height; ++row) {
|
||||
memcpy(dst, src, mappedData.stride);
|
||||
dst += mappedData.stride;
|
||||
src += data->mSourcePitch;
|
||||
}
|
||||
layers::CompositorThread()->Dispatch(NS_NewRunnableFunction(
|
||||
"webgpu::WebGPUParent::PresentCallback",
|
||||
[imageHost = data->mImageHost, texture = data->mTextureHost,
|
||||
frameID = data->mNextFrameID++]() {
|
||||
AutoTArray<layers::CompositableHost::TimedTexture, 1> textures;
|
||||
|
||||
layers::CompositableHost::TimedTexture* timedTexture =
|
||||
textures.AppendElement();
|
||||
|
||||
// TODO(aosmond): We recreate the WebRenderTextureHost object each
|
||||
// time so that the pipeline actually updates, as it checks if the
|
||||
// texture is the same as before issuing the transaction update to
|
||||
// WR. We really ought to be cycling between a front and buffer back
|
||||
// here to avoid a race uploading the texture and doing the copy in
|
||||
// PresentCallback.
|
||||
timedTexture->mTexture = new layers::WebRenderTextureHost(
|
||||
layers::TextureFlags::BORROWED_EXTERNAL_ID, texture,
|
||||
texture->GetMaybeExternalImageId().ref());
|
||||
timedTexture->mTimeStamp = TimeStamp();
|
||||
timedTexture->mPictureRect =
|
||||
gfx::IntRect(gfx::IntPoint(0, 0), texture->GetSize());
|
||||
timedTexture->mFrameID = frameID;
|
||||
timedTexture->mProducerID = 0;
|
||||
|
||||
imageHost->UseTextureHost(textures);
|
||||
}));
|
||||
req->mRemoteTextureOwner->PushTexture(req->mTextureId, req->mOwnerId,
|
||||
std::move(textureData),
|
||||
/* aSharedSurface */ nullptr);
|
||||
} else {
|
||||
NS_WARNING("WebGPU present skipped: the swapchain is resized!");
|
||||
}
|
||||
|
|
@ -862,53 +827,48 @@ static void PresentCallback(ffi::WGPUBufferMapAsyncStatus status,
|
|||
// TODO: better handle errors
|
||||
NS_WARNING("WebGPU frame mapping failed!");
|
||||
}
|
||||
// free yourself
|
||||
delete req;
|
||||
}
|
||||
|
||||
ipc::IPCResult WebGPUParent::GetFrontBufferSnapshot(
|
||||
IProtocol* aProtocol, const CompositableHandle& aHandle,
|
||||
IProtocol* aProtocol, const layers::RemoteTextureOwnerId& aOwnerId,
|
||||
Maybe<Shmem>& aShmem, gfx::IntSize& aSize) {
|
||||
const auto& lookup = mCanvasMap.find(aHandle.Value());
|
||||
if (lookup == mCanvasMap.end()) {
|
||||
const auto& lookup = mCanvasMap.find(aOwnerId);
|
||||
if (lookup == mCanvasMap.end() || !mRemoteTextureOwner) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<PresentationData> data = lookup->second.get();
|
||||
aSize = data->mTextureHost->GetSize();
|
||||
uint32_t stride =
|
||||
aSize.width * BytesPerPixel(data->mTextureHost->GetFormat());
|
||||
uint32_t len = data->mRowCount * stride;
|
||||
aSize = data->mDesc.size();
|
||||
uint32_t stride = layers::ImageDataSerializer::ComputeRGBStride(
|
||||
data->mDesc.format(), aSize.width);
|
||||
uint32_t len = data->mDesc.size().height * stride;
|
||||
Shmem shmem;
|
||||
if (!AllocShmem(len, &shmem)) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
uint8_t* dst = shmem.get<uint8_t>();
|
||||
uint8_t* src = data->mTextureHost->GetBuffer();
|
||||
for (uint32_t row = 0; row < data->mRowCount; ++row) {
|
||||
memcpy(dst, src, stride);
|
||||
src += data->mTargetPitch;
|
||||
dst += stride;
|
||||
}
|
||||
|
||||
mRemoteTextureOwner->GetLatestBufferSnapshot(aOwnerId, shmem, aSize);
|
||||
aShmem.emplace(std::move(shmem));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
ipc::IPCResult WebGPUParent::RecvSwapChainPresent(
|
||||
const CompositableHandle& aHandle, RawId aTextureId,
|
||||
RawId aCommandEncoderId) {
|
||||
RawId aTextureId, RawId aCommandEncoderId,
|
||||
const layers::RemoteTextureId& aRemoteTextureId,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId) {
|
||||
// step 0: get the data associated with the swapchain
|
||||
const auto& lookup = mCanvasMap.find(aHandle.Value());
|
||||
if (lookup == mCanvasMap.end()) {
|
||||
const auto& lookup = mCanvasMap.find(aOwnerId);
|
||||
if (lookup == mCanvasMap.end() || !mRemoteTextureOwner ||
|
||||
!mRemoteTextureOwner->IsRegistered(aOwnerId)) {
|
||||
NS_WARNING("WebGPU presenting on a destroyed swap chain!");
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<PresentationData> data = lookup->second.get();
|
||||
RawId bufferId = 0;
|
||||
const auto& size = data->mTextureHost->GetSize();
|
||||
const auto bufferSize = data->mRowCount * data->mSourcePitch;
|
||||
const auto& size = data->mDesc.size();
|
||||
const auto bufferSize = data->mDesc.size().height * data->mSourcePitch;
|
||||
|
||||
// step 1: find an available staging buffer, or create one
|
||||
{
|
||||
|
|
@ -1001,13 +961,11 @@ ipc::IPCResult WebGPUParent::RecvSwapChainPresent(
|
|||
// texture,
|
||||
// we can just give it the contents of the last mapped buffer instead of the
|
||||
// copy.
|
||||
auto* const presentRequest = new PresentRequest{
|
||||
mContext.get(),
|
||||
data,
|
||||
};
|
||||
auto presentRequest = MakeUnique<PresentRequest>(
|
||||
mContext.get(), data, mRemoteTextureOwner, aRemoteTextureId, aOwnerId);
|
||||
|
||||
ffi::WGPUBufferMapCallbackC callback = {
|
||||
&PresentCallback, reinterpret_cast<uint8_t*>(presentRequest)};
|
||||
&PresentCallback, reinterpret_cast<uint8_t*>(presentRequest.release())};
|
||||
ffi::wgpu_server_buffer_map(mContext.get(), bufferId, 0, bufferSize,
|
||||
ffi::WGPUHostMap_Read, callback);
|
||||
|
||||
|
|
@ -1015,8 +973,11 @@ ipc::IPCResult WebGPUParent::RecvSwapChainPresent(
|
|||
}
|
||||
|
||||
ipc::IPCResult WebGPUParent::RecvSwapChainDestroy(
|
||||
const CompositableHandle& aHandle) {
|
||||
const auto& lookup = mCanvasMap.find(aHandle.Value());
|
||||
const layers::RemoteTextureOwnerId& aOwnerId) {
|
||||
if (mRemoteTextureOwner) {
|
||||
mRemoteTextureOwner->UnregisterTextureOwner(aOwnerId);
|
||||
}
|
||||
const auto& lookup = mCanvasMap.find(aOwnerId);
|
||||
MOZ_ASSERT(lookup != mCanvasMap.end());
|
||||
if (lookup == mCanvasMap.end()) {
|
||||
NS_WARNING("WebGPU presenting on a destroyed swap chain!");
|
||||
|
|
@ -1025,8 +986,6 @@ ipc::IPCResult WebGPUParent::RecvSwapChainDestroy(
|
|||
|
||||
RefPtr<PresentationData> data = lookup->second.get();
|
||||
mCanvasMap.erase(lookup);
|
||||
data->mTextureHost = nullptr;
|
||||
layers::CompositableInProcessManager::Release(aHandle, OtherPid());
|
||||
|
||||
MutexAutoLock lock(data->mBuffersLock);
|
||||
ipc::ByteBuf dropByteBuf;
|
||||
|
|
@ -1047,11 +1006,11 @@ ipc::IPCResult WebGPUParent::RecvSwapChainDestroy(
|
|||
|
||||
void WebGPUParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
mTimer.Stop();
|
||||
for (const auto& p : mCanvasMap) {
|
||||
const CompositableHandle handle(p.first);
|
||||
layers::CompositableInProcessManager::Release(handle, OtherPid());
|
||||
}
|
||||
mCanvasMap.clear();
|
||||
if (mRemoteTextureOwner) {
|
||||
mRemoteTextureOwner->UnregisterAllTextureOwners();
|
||||
mRemoteTextureOwner = nullptr;
|
||||
}
|
||||
ffi::wgpu_server_poll_all_devices(mContext.get(), true);
|
||||
mContext = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,14 @@
|
|||
#include "WebGPUTypes.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace mozilla::webgpu {
|
||||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
class RemoteTextureOwnerClient;
|
||||
} // namespace layers
|
||||
|
||||
namespace webgpu {
|
||||
|
||||
class ErrorBuffer;
|
||||
class PresentationData;
|
||||
|
||||
|
|
@ -68,18 +75,20 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
ipc::IPCResult RecvRenderPipelineDestroy(RawId aPipelineId);
|
||||
ipc::IPCResult RecvImplicitLayoutDestroy(
|
||||
RawId aImplicitPlId, const nsTArray<RawId>& aImplicitBglIds);
|
||||
ipc::IPCResult RecvDeviceCreateSwapChain(RawId aDeviceId, RawId aQueueId,
|
||||
const layers::RGBDescriptor& aDesc,
|
||||
const nsTArray<RawId>& aBufferIds,
|
||||
const CompositableHandle& aHandle);
|
||||
ipc::IPCResult RecvDeviceCreateSwapChain(
|
||||
RawId aDeviceId, RawId aQueueId, const layers::RGBDescriptor& aDesc,
|
||||
const nsTArray<RawId>& aBufferIds,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId);
|
||||
ipc::IPCResult RecvDeviceCreateShaderModule(
|
||||
RawId aDeviceId, RawId aModuleId, const nsString& aLabel,
|
||||
const nsCString& aCode, DeviceCreateShaderModuleResolver&& aOutMessage);
|
||||
|
||||
ipc::IPCResult RecvSwapChainPresent(const CompositableHandle& aHandle,
|
||||
RawId aTextureId,
|
||||
RawId aCommandEncoderId);
|
||||
ipc::IPCResult RecvSwapChainDestroy(const CompositableHandle& aHandle);
|
||||
ipc::IPCResult RecvSwapChainPresent(
|
||||
RawId aTextureId, RawId aCommandEncoderId,
|
||||
const layers::RemoteTextureId& aRemoteTextureId,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId);
|
||||
ipc::IPCResult RecvSwapChainDestroy(
|
||||
const layers::RemoteTextureOwnerId& aOwnerId);
|
||||
|
||||
ipc::IPCResult RecvDeviceAction(RawId aDeviceId,
|
||||
const ipc::ByteBuf& aByteBuf);
|
||||
|
|
@ -100,10 +109,9 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
RawId aDeviceId, DevicePopErrorScopeResolver&& aResolver);
|
||||
ipc::IPCResult RecvGenerateError(RawId aDeviceId, const nsCString& message);
|
||||
|
||||
ipc::IPCResult GetFrontBufferSnapshot(IProtocol* aProtocol,
|
||||
const CompositableHandle& aHandle,
|
||||
Maybe<Shmem>& aShmem,
|
||||
gfx::IntSize& aSize);
|
||||
ipc::IPCResult GetFrontBufferSnapshot(
|
||||
IProtocol* aProtocol, const layers::RemoteTextureOwnerId& aOwnerId,
|
||||
Maybe<Shmem>& aShmem, gfx::IntSize& aSize);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
|
|
@ -133,11 +141,17 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
/// regardless of their state.
|
||||
std::unordered_map<uint64_t, BufferMapData> mSharedMemoryMap;
|
||||
/// Associated presentation data for each swapchain.
|
||||
std::unordered_map<uint64_t, RefPtr<PresentationData>> mCanvasMap;
|
||||
std::unordered_map<layers::RemoteTextureOwnerId, RefPtr<PresentationData>,
|
||||
layers::RemoteTextureOwnerId::HashFn>
|
||||
mCanvasMap;
|
||||
|
||||
RefPtr<layers::RemoteTextureOwnerClient> mRemoteTextureOwner;
|
||||
|
||||
/// Associated stack of error scopes for each device.
|
||||
std::unordered_map<uint64_t, ErrorScopeStack> mErrorScopeMap;
|
||||
};
|
||||
|
||||
} // namespace mozilla::webgpu
|
||||
} // namespace webgpu
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WEBGPU_PARENT_H_
|
||||
|
|
|
|||
|
|
@ -145,14 +145,14 @@ RefPtr<webgpu::WebGPUChild> CanvasManagerChild::GetWebGPUChild() {
|
|||
|
||||
already_AddRefed<DataSourceSurface> CanvasManagerChild::GetSnapshot(
|
||||
uint32_t aManagerId, int32_t aProtocolId,
|
||||
const layers::CompositableHandle& aHandle, SurfaceFormat aFormat,
|
||||
const Maybe<RemoteTextureOwnerId>& aOwnerId, SurfaceFormat aFormat,
|
||||
bool aPremultiply, bool aYFlip) {
|
||||
if (!CanSend()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
webgl::FrontBufferSnapshotIpc res;
|
||||
if (!SendGetSnapshot(aManagerId, aProtocolId, aHandle, &res)) {
|
||||
if (!SendGetSnapshot(aManagerId, aProtocolId, aOwnerId, &res)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class CanvasManagerChild final : public PCanvasManagerChild {
|
|||
uint32_t Id() const { return mId; }
|
||||
already_AddRefed<DataSourceSurface> GetSnapshot(
|
||||
uint32_t aManagerId, int32_t aProtocolId,
|
||||
const layers::CompositableHandle& aHandle, SurfaceFormat aFormat,
|
||||
const Maybe<RemoteTextureOwnerId>& aOwnerId, SurfaceFormat aFormat,
|
||||
bool aPremultiply, bool aYFlip);
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvInitialize(
|
|||
|
||||
mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
|
||||
const uint32_t& aManagerId, const int32_t& aProtocolId,
|
||||
const CompositableHandle& aHandle, webgl::FrontBufferSnapshotIpc* aResult) {
|
||||
const Maybe<RemoteTextureOwnerId>& aOwnerId,
|
||||
webgl::FrontBufferSnapshotIpc* aResult) {
|
||||
if (!aManagerId) {
|
||||
return IPC_FAIL(this, "invalid id");
|
||||
}
|
||||
|
|
@ -157,8 +158,11 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
|
|||
RefPtr<webgpu::WebGPUParent> webgpu =
|
||||
static_cast<webgpu::WebGPUParent*>(actor);
|
||||
IntSize size;
|
||||
if (aOwnerId.isNothing()) {
|
||||
return IPC_FAIL(this, "invalid OwnerId");
|
||||
}
|
||||
mozilla::ipc::IPCResult rv =
|
||||
webgpu->GetFrontBufferSnapshot(this, aHandle, buffer.shmem, size);
|
||||
webgpu->GetFrontBufferSnapshot(this, *aOwnerId, buffer.shmem, size);
|
||||
if (!rv) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class CanvasManagerParent final : public PCanvasManagerParent {
|
|||
mozilla::ipc::IPCResult RecvInitialize(const uint32_t& aId);
|
||||
mozilla::ipc::IPCResult RecvGetSnapshot(
|
||||
const uint32_t& aManagerId, const int32_t& aProtocolId,
|
||||
const CompositableHandle& aHandle,
|
||||
const Maybe<RemoteTextureOwnerId>& aOwnerId,
|
||||
webgl::FrontBufferSnapshotIpc* aResult);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ include "mozilla/layers/LayersMessageUtils.h";
|
|||
include protocol PWebGL;
|
||||
include protocol PWebGPU;
|
||||
|
||||
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
|
||||
using layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h";
|
||||
using mozilla::webgl::FrontBufferSnapshotIpc from "mozilla/dom/WebGLIpdl.h";
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -41,7 +41,7 @@ parent:
|
|||
// intended to be used by the main thread in the content process to block
|
||||
// reading without having to block on the worker thread that owns the context
|
||||
// instance.
|
||||
sync GetSnapshot(uint32_t aManagerId, int32_t aProtocolId, CompositableHandle aHandle) returns (FrontBufferSnapshotIpc ret);
|
||||
sync GetSnapshot(uint32_t aManagerId, int32_t aProtocolId, RemoteTextureOwnerId? ownerId) returns (FrontBufferSnapshotIpc ret);
|
||||
};
|
||||
|
||||
} // gfx
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@
|
|||
#include "mozilla/Preferences.h" // for Preferences
|
||||
#include "mozilla/RefPtr.h" // for RefPtr
|
||||
#include "mozilla/gfx/2D.h" // for DrawTarget
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "mozilla/WeakPtr.h" // for WeakPtr
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "mozilla/WeakPtr.h" // for WeakPtr
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -46,6 +47,9 @@ struct CanvasRendererData final {
|
|||
|
||||
gl::OriginPos mOriginPos = gl::OriginPos::TopLeft;
|
||||
|
||||
// Used in remote texture push callback
|
||||
Maybe<RemoteTextureOwnerId> mRemoteTextureOwnerIdOfPushCallback = Nothing();
|
||||
|
||||
nsICanvasRenderingContextInternal* GetContext() const {
|
||||
return mContext.get();
|
||||
}
|
||||
|
|
@ -122,6 +126,9 @@ class CanvasRenderer : public RefCounted<CanvasRenderer> {
|
|||
const gfx::IntSize& GetSize() const { return mData.mSize; }
|
||||
bool IsOpaque() const { return mData.mIsOpaque; }
|
||||
bool YIsDown() const { return mData.mOriginPos == gl::OriginPos::TopLeft; }
|
||||
Maybe<RemoteTextureOwnerId> GetRemoteTextureOwnerIdOfPushCallback() {
|
||||
return mData.mRemoteTextureOwnerIdOfPushCallback;
|
||||
}
|
||||
|
||||
void SetDirty() { mDirty = true; }
|
||||
void ResetDirty() { mDirty = false; }
|
||||
|
|
|
|||
|
|
@ -326,7 +326,6 @@ class CompositableHandle final {
|
|||
enum class CompositableHandleOwner : uint8_t {
|
||||
WebRenderBridge,
|
||||
ImageBridge,
|
||||
InProcessManager,
|
||||
};
|
||||
|
||||
struct RemoteTextureId {
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "CompositableHost.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/AsyncImagePipelineManager.h"
|
||||
#include "mozilla/layers/BufferTexture.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/RemoteTextureHostWrapper.h"
|
||||
#include "mozilla/layers/WebRenderTextureHost.h"
|
||||
#include "mozilla/StaticPrefs_webgl.h"
|
||||
|
|
@ -36,10 +38,10 @@ bool RemoteTextureOwnerClient::IsRegistered(
|
|||
}
|
||||
|
||||
void RemoteTextureOwnerClient::RegisterTextureOwner(
|
||||
const RemoteTextureOwnerId aOwnerId) {
|
||||
const RemoteTextureOwnerId aOwnerId, bool aIsSyncMode) {
|
||||
MOZ_ASSERT(mOwnerIds.find(aOwnerId) == mOwnerIds.end());
|
||||
mOwnerIds.emplace(aOwnerId);
|
||||
RemoteTextureMap::Get()->RegisterTextureOwner(aOwnerId, mForPid);
|
||||
RemoteTextureMap::Get()->RegisterTextureOwner(aOwnerId, mForPid, aIsSyncMode);
|
||||
}
|
||||
|
||||
void RemoteTextureOwnerClient::UnregisterTextureOwner(
|
||||
|
|
@ -68,6 +70,14 @@ void RemoteTextureOwnerClient::PushTexture(
|
|||
std::move(aTextureData), aSharedSurface);
|
||||
}
|
||||
|
||||
void RemoteTextureOwnerClient::GetLatestBufferSnapshot(
|
||||
const RemoteTextureOwnerId aOwnerId, const ipc::Shmem& aDestShmem,
|
||||
const gfx::IntSize& aSize) {
|
||||
MOZ_ASSERT(IsRegistered(aOwnerId));
|
||||
RemoteTextureMap::Get()->GetLatestBufferSnapshot(aOwnerId, mForPid,
|
||||
aDestShmem, aSize);
|
||||
}
|
||||
|
||||
UniquePtr<TextureData>
|
||||
RemoteTextureOwnerClient::CreateOrRecycleBufferTextureData(
|
||||
const RemoteTextureOwnerId aOwnerId, gfx::IntSize aSize,
|
||||
|
|
@ -133,6 +143,19 @@ void RemoteTextureMap::PushTexture(
|
|||
return;
|
||||
}
|
||||
|
||||
const auto key = std::pair(aForPid, aOwnerId);
|
||||
auto it = mRemoteTexturePushListeners.find(key);
|
||||
// Notify a new texture if callback is requested
|
||||
if (it != mRemoteTexturePushListeners.end()) {
|
||||
RefPtr<CompositableHost> compositableHost = it->second;
|
||||
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
||||
"RemoteTextureMap::PushTexture::Runnable",
|
||||
[compositableHost, aTextureId, aOwnerId, aForPid]() {
|
||||
compositableHost->NotifyPushTexture(aTextureId, aOwnerId, aForPid);
|
||||
});
|
||||
CompositorThread()->Dispatch(runnable.forget());
|
||||
}
|
||||
|
||||
auto textureData = MakeUnique<TextureDataHolder>(
|
||||
aTextureId, textureHost, std::move(aTextureData), aSharedSurface);
|
||||
|
||||
|
|
@ -140,7 +163,7 @@ void RemoteTextureMap::PushTexture(
|
|||
|
||||
owner->mWaitingTextureDataHolders.push_back(std::move(textureData));
|
||||
|
||||
if (!gfx::gfxVars::WebglOopAsyncPresentForceSync()) {
|
||||
if (!owner->mIsSyncMode) {
|
||||
// Update mAsyncRemoteTextureHost for async mode.
|
||||
// This happens when PushTexture() with RemoteTextureId is called after
|
||||
// GetRemoteTextureForDisplayList() with the RemoteTextureId.
|
||||
|
|
@ -183,8 +206,77 @@ void RemoteTextureMap::PushTexture(
|
|||
}
|
||||
}
|
||||
|
||||
void RemoteTextureMap::GetLatestBufferSnapshot(
|
||||
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
||||
const ipc::Shmem& aDestShmem, const gfx::IntSize& aSize) {
|
||||
// The compositable ref of remote texture should be updated in mMonitor lock.
|
||||
CompositableTextureHostRef textureHostRef;
|
||||
RefPtr<TextureHost> releasingTexture; // Release outside the monitor
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
||||
if (!owner) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get latest TextureHost of remote Texture.
|
||||
if (owner->mWaitingTextureDataHolders.empty() &&
|
||||
!owner->mLatestTextureHost) {
|
||||
return;
|
||||
}
|
||||
TextureHost* textureHost =
|
||||
!owner->mWaitingTextureDataHolders.empty()
|
||||
? owner->mWaitingTextureDataHolders.back()->mTextureHost
|
||||
: owner->mLatestTextureHost;
|
||||
if (!textureHost->AsBufferTextureHost()) {
|
||||
// Only BufferTextureHost is supported for now.
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return;
|
||||
}
|
||||
if (textureHost->GetSize() != aSize) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return;
|
||||
}
|
||||
if (textureHost->GetFormat() != gfx::SurfaceFormat::R8G8B8A8 &&
|
||||
textureHost->GetFormat() != gfx::SurfaceFormat::B8G8R8A8) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return;
|
||||
}
|
||||
// Increment compositable ref to prevent that TextureHost is removed during
|
||||
// memcpy.
|
||||
textureHostRef = textureHost;
|
||||
}
|
||||
|
||||
if (!textureHostRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* bufferTextureHost = textureHostRef->AsBufferTextureHost();
|
||||
if (bufferTextureHost) {
|
||||
uint32_t stride = ImageDataSerializer::ComputeRGBStride(
|
||||
bufferTextureHost->GetFormat(), aSize.width);
|
||||
uint32_t bufferSize = stride * aSize.height;
|
||||
uint8_t* dst = aDestShmem.get<uint8_t>();
|
||||
uint8_t* src = bufferTextureHost->GetBuffer();
|
||||
|
||||
MOZ_ASSERT(bufferSize <= aDestShmem.Size<uint8_t>());
|
||||
memcpy(dst, src, bufferSize);
|
||||
}
|
||||
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
// Release compositable ref in mMonitor lock, but release RefPtr outside the
|
||||
// monitor
|
||||
releasingTexture = textureHostRef;
|
||||
textureHostRef = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteTextureMap::RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid) {
|
||||
const base::ProcessId aForPid,
|
||||
bool aIsSyncMode) {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
const auto key = std::pair(aForPid, aOwnerId);
|
||||
|
|
@ -194,6 +286,8 @@ void RemoteTextureMap::RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId,
|
|||
return;
|
||||
}
|
||||
auto owner = MakeUnique<TextureOwner>();
|
||||
owner->mIsSyncMode = aIsSyncMode;
|
||||
|
||||
mTextureOwners.emplace(key, std::move(owner));
|
||||
}
|
||||
|
||||
|
|
@ -367,7 +461,7 @@ void RemoteTextureMap::GetRemoteTextureForDisplayList(
|
|||
|
||||
UpdateTexture(lock, owner, textureId);
|
||||
|
||||
if (gfx::gfxVars::WebglOopAsyncPresentForceSync()) {
|
||||
if (owner->mIsSyncMode) {
|
||||
// remote texture sync ipc
|
||||
if (textureId == owner->mLatestTextureId) {
|
||||
MOZ_ASSERT(owner->mLatestTextureHost);
|
||||
|
|
@ -412,8 +506,8 @@ void RemoteTextureMap::GetRemoteTextureForDisplayList(
|
|||
}
|
||||
|
||||
if (textureHost) {
|
||||
aTextureHostWrapper->SetRemoteTextureHostForDisplayList(lock,
|
||||
textureHost);
|
||||
aTextureHostWrapper->SetRemoteTextureHostForDisplayList(
|
||||
lock, textureHost, owner->mIsSyncMode);
|
||||
aTextureHostWrapper->ApplyTextureFlagsToRemoteTexture();
|
||||
}
|
||||
}
|
||||
|
|
@ -483,7 +577,7 @@ void RemoteTextureMap::ReleaseRemoteTextureHostForDisplayList(
|
|||
MonitorAutoLock lock(mMonitor);
|
||||
releasingTexture =
|
||||
aTextureHostWrapper->GetRemoteTextureHostForDisplayList(lock);
|
||||
aTextureHostWrapper->SetRemoteTextureHostForDisplayList(lock, nullptr);
|
||||
aTextureHostWrapper->ClearRemoteTextureHostForDisplayList(lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -535,6 +629,74 @@ void RemoteTextureMap::UnregisterRemoteTextureHostWrapper(
|
|||
}
|
||||
}
|
||||
|
||||
void RemoteTextureMap::RegisterRemoteTexturePushListener(
|
||||
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
||||
CompositableHost* aListener) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
RefPtr<CompositableHost>
|
||||
releasingCompositableHost; // Release outside the monitor
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
const auto key = std::pair(aForPid, aOwnerId);
|
||||
auto it = mRemoteTexturePushListeners.find(key);
|
||||
// Remove obsoleted CompositableHost.
|
||||
if (it != mRemoteTexturePushListeners.end()) {
|
||||
releasingCompositableHost = std::move(it->second);
|
||||
mRemoteTexturePushListeners.erase(it);
|
||||
}
|
||||
mRemoteTexturePushListeners.emplace(key, aListener);
|
||||
|
||||
auto* owner = GetTextureOwner(lock, aOwnerId, aForPid);
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
if (owner->mWaitingTextureDataHolders.empty() &&
|
||||
!owner->mLatestTextureHost) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get latest RemoteTextureId.
|
||||
auto textureId = !owner->mWaitingTextureDataHolders.empty()
|
||||
? owner->mWaitingTextureDataHolders.back()->mTextureId
|
||||
: owner->mLatestTextureId;
|
||||
|
||||
// Notify the RemoteTextureId to callback
|
||||
RefPtr<CompositableHost> compositableHost = aListener;
|
||||
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
||||
"RemoteTextureMap::RegisterRemoteTexturePushListener::Runnable",
|
||||
[compositableHost, textureId, aOwnerId, aForPid]() {
|
||||
compositableHost->NotifyPushTexture(textureId, aOwnerId, aForPid);
|
||||
});
|
||||
CompositorThread()->Dispatch(runnable.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteTextureMap::UnregisterRemoteTexturePushListener(
|
||||
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
||||
CompositableHost* aListener) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
RefPtr<CompositableHost>
|
||||
releasingCompositableHost; // Release outside the monitor
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
const auto key = std::pair(aForPid, aOwnerId);
|
||||
auto it = mRemoteTexturePushListeners.find(key);
|
||||
if (it == mRemoteTexturePushListeners.end()) {
|
||||
return;
|
||||
}
|
||||
if (aListener != it->second) {
|
||||
// aListener was alredy obsoleted.
|
||||
return;
|
||||
}
|
||||
releasingCompositableHost = std::move(it->second);
|
||||
mRemoteTexturePushListeners.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
UniquePtr<TextureData> RemoteTextureMap::GetRecycledBufferTextureData(
|
||||
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class SharedSurface;
|
|||
|
||||
namespace layers {
|
||||
|
||||
class CompositableHost;
|
||||
class RemoteTextureHostWrapper;
|
||||
class TextureData;
|
||||
class TextureHost;
|
||||
|
|
@ -50,13 +51,17 @@ class RemoteTextureOwnerClient final {
|
|||
explicit RemoteTextureOwnerClient(const base::ProcessId aForPid);
|
||||
|
||||
bool IsRegistered(const RemoteTextureOwnerId aOwnerId);
|
||||
void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId);
|
||||
void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId,
|
||||
bool aIsSyncMode);
|
||||
void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerId);
|
||||
void UnregisterAllTextureOwners();
|
||||
void PushTexture(const RemoteTextureId aTextureId,
|
||||
const RemoteTextureOwnerId aOwnerId,
|
||||
UniquePtr<TextureData>&& aTextureData,
|
||||
const std::shared_ptr<gl::SharedSurface>& aSharedSurface);
|
||||
void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId,
|
||||
const ipc::Shmem& aDestShmem,
|
||||
const gfx::IntSize& aSize);
|
||||
UniquePtr<TextureData> CreateOrRecycleBufferTextureData(
|
||||
const RemoteTextureOwnerId aOwnerId, gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat);
|
||||
|
|
@ -95,8 +100,16 @@ class RemoteTextureMap {
|
|||
const base::ProcessId aForPid,
|
||||
UniquePtr<TextureData>&& aTextureData,
|
||||
const std::shared_ptr<gl::SharedSurface>& aSharedSurface);
|
||||
|
||||
void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid,
|
||||
const ipc::Shmem& aDestShmem,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
// aIsSyncMode defines if RemoteTextureMap::GetRemoteTextureForDisplayList()
|
||||
// works synchronously.
|
||||
void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid);
|
||||
const base::ProcessId aForPid, bool aIsSyncMode);
|
||||
void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerIds,
|
||||
const base::ProcessId aForPid);
|
||||
void UnregisterTextureOwners(
|
||||
|
|
@ -129,6 +142,14 @@ class RemoteTextureMap {
|
|||
const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid);
|
||||
|
||||
void RegisterRemoteTexturePushListener(const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid,
|
||||
CompositableHost* aListener);
|
||||
|
||||
void UnregisterRemoteTexturePushListener(const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid,
|
||||
CompositableHost* aListener);
|
||||
|
||||
UniquePtr<TextureData> GetRecycledBufferTextureData(
|
||||
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
|
||||
|
|
@ -157,6 +178,7 @@ class RemoteTextureMap {
|
|||
};
|
||||
|
||||
struct TextureOwner {
|
||||
bool mIsSyncMode = true;
|
||||
// Holds TextureDataHolders that wait to be used for building wr display
|
||||
// list.
|
||||
std::deque<UniquePtr<TextureDataHolder>> mWaitingTextureDataHolders;
|
||||
|
|
@ -204,6 +226,10 @@ class RemoteTextureMap {
|
|||
UniquePtr<RemoteTextureHostWrapperHolder>>
|
||||
mRemoteTextureHostWrapperHolders;
|
||||
|
||||
std::map<std::pair<base::ProcessId, RemoteTextureOwnerId>,
|
||||
RefPtr<CompositableHost>>
|
||||
mRemoteTexturePushListeners;
|
||||
|
||||
static StaticAutoPtr<RemoteTextureMap> sInstance;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,16 @@ void ShareableCanvasRenderer::UpdateCompositableClient() {
|
|||
flags |= TextureFlags::IS_OPAQUE;
|
||||
}
|
||||
|
||||
// With remote texture push callback, a new pushed remote texture is notifiled
|
||||
// from RemoteTextureMap to WebRenderImageHost.
|
||||
if (mData.mRemoteTextureOwnerIdOfPushCallback) {
|
||||
GetForwarder()->EnableRemoteTexturePushCallback(
|
||||
mCanvasClient, *mData.mRemoteTextureOwnerIdOfPushCallback, mData.mSize,
|
||||
flags);
|
||||
EnsurePipeline();
|
||||
return;
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
const auto fnGetExistingTc =
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@
|
|||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/RefPtr.h" // for RefPtr, RefCounted, etc
|
||||
//#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
|
||||
// #include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
|
||||
#include "mozilla/gfx/Polygon.h" // for Polygon
|
||||
#include "mozilla/gfx/Rect.h" // for Rect
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
|
||||
//#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
|
||||
// #include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
|
||||
#include "mozilla/layers/LayersMessages.h"
|
||||
#include "mozilla/layers/TextureHost.h" // for TextureHost
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
|
|
@ -93,6 +93,15 @@ class CompositableHost {
|
|||
const TextureFlags aFlags) = 0;
|
||||
virtual void RemoveTextureHost(TextureHost* aTexture);
|
||||
|
||||
// Enable remote texture push callback
|
||||
virtual void EnableRemoteTexturePushCallback(
|
||||
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
||||
const gfx::IntSize aSize, const TextureFlags aFlags) = 0;
|
||||
// Called from RemoteTextureMap when a new remote texture is pushed
|
||||
virtual void NotifyPushTexture(const RemoteTextureId aTextureId,
|
||||
const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid) = 0;
|
||||
|
||||
uint64_t GetCompositorBridgeID() const { return mCompositorBridgeID; }
|
||||
|
||||
const AsyncCompositableRef& GetAsyncRef() const { return mAsyncRef; }
|
||||
|
|
|
|||
|
|
@ -96,8 +96,9 @@ void RemoteTextureHostWrapper::CreateRenderTexture(
|
|||
MOZ_ASSERT(mRemoteTextureForDisplayList);
|
||||
MOZ_ASSERT(mRemoteTextureForDisplayList->mExternalImageId.isSome());
|
||||
|
||||
if (gfx::gfxVars::WebglOopAsyncPresentForceSync()) {
|
||||
if (mIsSyncMode) {
|
||||
// sync mode
|
||||
// mRemoteTextureForDisplayList is also used for WebRender rendering.
|
||||
auto wrappedId = mRemoteTextureForDisplayList->mExternalImageId.ref();
|
||||
RefPtr<wr::RenderTextureHost> texture =
|
||||
new wr::RenderTextureHostWrapper(wrappedId);
|
||||
|
|
@ -105,6 +106,9 @@ void RemoteTextureHostWrapper::CreateRenderTexture(
|
|||
texture.forget());
|
||||
} else {
|
||||
// async mode
|
||||
// mRemoteTextureForDisplayList could be previous remote texture's
|
||||
// TextureHost that is compatible to the mTextureId's TextureHost.
|
||||
// mRemoteTextureForDisplayList might not be used WebRender rendering.
|
||||
RefPtr<wr::RenderTextureHost> texture =
|
||||
new wr::RenderTextureHostWrapper(mTextureId, mOwnerId, mForPid);
|
||||
wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId.ref(),
|
||||
|
|
@ -203,9 +207,17 @@ TextureHost* RemoteTextureHostWrapper::GetRemoteTextureHostForDisplayList(
|
|||
}
|
||||
|
||||
void RemoteTextureHostWrapper::SetRemoteTextureHostForDisplayList(
|
||||
const MonitorAutoLock& aProofOfLock, TextureHost* aTextureHost) {
|
||||
const MonitorAutoLock& aProofOfLock, TextureHost* aTextureHost,
|
||||
bool aIsSyncMode) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
mRemoteTextureForDisplayList = aTextureHost;
|
||||
mIsSyncMode = aIsSyncMode;
|
||||
}
|
||||
|
||||
void RemoteTextureHostWrapper::ClearRemoteTextureHostForDisplayList(
|
||||
const MonitorAutoLock& aProofOfLoc) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
mRemoteTextureForDisplayList = nullptr;
|
||||
}
|
||||
|
||||
bool RemoteTextureHostWrapper::IsWrappingSurfaceTextureHost() {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ class RemoteTextureHostWrapper : public TextureHost {
|
|||
const MonitorAutoLock& aProofOfLock);
|
||||
// Called only by RemoteTextureMap
|
||||
void SetRemoteTextureHostForDisplayList(const MonitorAutoLock& aProofOfLock,
|
||||
TextureHost* aTextureHost);
|
||||
TextureHost* aTextureHost,
|
||||
bool aIsSyncMode);
|
||||
void ClearRemoteTextureHostForDisplayList(
|
||||
const MonitorAutoLock& aProofOfLock);
|
||||
|
||||
// Updated by RemoteTextureMap
|
||||
//
|
||||
|
|
@ -107,6 +110,8 @@ class RemoteTextureHostWrapper : public TextureHost {
|
|||
// compatible to the mTextureId's TextureHost.
|
||||
CompositableTextureHostRef mRemoteTextureForDisplayList;
|
||||
|
||||
bool mIsSyncMode = true;
|
||||
|
||||
friend class RemoteTextureMap;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,9 @@ class CompositableForwarder : public KnowsCompositor {
|
|||
const gfx::IntSize aSize,
|
||||
const TextureFlags aFlags) = 0;
|
||||
|
||||
virtual void EnableAsyncCompositable(CompositableClient* aCompositable,
|
||||
bool aEnable) = 0;
|
||||
virtual void EnableRemoteTexturePushCallback(
|
||||
CompositableClient* aCompositable, const RemoteTextureOwnerId aOwnerId,
|
||||
const gfx::IntSize aSize, const TextureFlags aFlags) = 0;
|
||||
|
||||
virtual void UpdateFwdTransactionId() = 0;
|
||||
virtual uint64_t GetFwdTransactionId() = 0;
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CompositableInProcessManager.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
|
||||
namespace mozilla::layers {
|
||||
|
||||
std::map<std::pair<base::ProcessId, uint64_t>, RefPtr<WebRenderImageHost>>
|
||||
CompositableInProcessManager::sCompositables;
|
||||
StaticMutex CompositableInProcessManager::sMutex;
|
||||
|
||||
uint32_t CompositableInProcessManager::sNamespace(0);
|
||||
Atomic<uint32_t> CompositableInProcessManager::sNextResourceId(1);
|
||||
Atomic<uint64_t> CompositableInProcessManager::sNextHandle(1);
|
||||
|
||||
/* static */ void CompositableInProcessManager::Initialize(
|
||||
uint32_t aNamespace) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sNamespace = aNamespace;
|
||||
}
|
||||
|
||||
/* static */ void CompositableInProcessManager::Shutdown() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
sCompositables.clear();
|
||||
}
|
||||
|
||||
/* static */ RefPtr<WebRenderImageHost> CompositableInProcessManager::Add(
|
||||
const CompositableHandle& aHandle, base::ProcessId aForPid,
|
||||
const TextureInfo& aTextureInfo) {
|
||||
MOZ_RELEASE_ASSERT(aHandle.Value());
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
|
||||
const auto key = std::pair(aForPid, aHandle.Value());
|
||||
if (sCompositables.find(key) != sCompositables.end()) {
|
||||
MOZ_ASSERT_UNREACHABLE("Duplicate handle!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto host = MakeRefPtr<WebRenderImageHost>(aTextureInfo);
|
||||
sCompositables[key] = host;
|
||||
host->SetAsyncRef(AsyncCompositableRef(aForPid, aHandle));
|
||||
return host;
|
||||
}
|
||||
|
||||
/* static */ RefPtr<WebRenderImageHost> CompositableInProcessManager::Find(
|
||||
const CompositableHandle& aHandle, base::ProcessId aForPid) {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
|
||||
const auto key = std::pair(aForPid, aHandle.Value());
|
||||
const auto i = sCompositables.find(key);
|
||||
if (NS_WARN_IF(i == sCompositables.end())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
/* static */ void CompositableInProcessManager::Release(
|
||||
const CompositableHandle& aHandle, base::ProcessId aForPid) {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
|
||||
const auto key = std::pair(aForPid, aHandle.Value());
|
||||
const auto i = sCompositables.find(key);
|
||||
if (NS_WARN_IF(i == sCompositables.end())) {
|
||||
return;
|
||||
}
|
||||
|
||||
sCompositables.erase(i);
|
||||
}
|
||||
|
||||
} // namespace mozilla::layers
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/layers/WebRenderImageHost.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
namespace mozilla::layers {
|
||||
|
||||
/**
|
||||
* CompostaibleInProcessManager is responsible for tracking textures that the
|
||||
* content process knows nothing about, beyond the CompositableHandle itself
|
||||
* for the purpose of binding to an AsyncImagePipeline in the display list.
|
||||
*
|
||||
* Hence the compositor process is responsible for creating and updating the
|
||||
* WebRenderImageHost object. This will allow frames to be composited without
|
||||
* interacting with the content process.
|
||||
*/
|
||||
class CompositableInProcessManager final {
|
||||
public:
|
||||
static void Initialize(uint32_t aNamespace);
|
||||
static void Shutdown();
|
||||
|
||||
static RefPtr<WebRenderImageHost> Add(const CompositableHandle& aHandle,
|
||||
base::ProcessId aForPid,
|
||||
const TextureInfo& aTextureInfo);
|
||||
static RefPtr<WebRenderImageHost> Find(const CompositableHandle& aHandle,
|
||||
base::ProcessId aForPid);
|
||||
static void Release(const CompositableHandle& aHandle,
|
||||
base::ProcessId aForPid);
|
||||
|
||||
static CompositableHandle GetNextHandle() {
|
||||
return CompositableHandle(sNextHandle++);
|
||||
}
|
||||
|
||||
static uint32_t GetNextResourceId() {
|
||||
uint32_t resourceId = sNextResourceId++;
|
||||
MOZ_RELEASE_ASSERT(resourceId != 0);
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
static wr::ExternalImageId GetNextExternalImageId() {
|
||||
return wr::ToExternalImageId(GetShiftedNamespace() | GetNextResourceId());
|
||||
}
|
||||
|
||||
private:
|
||||
static uint64_t GetShiftedNamespace() {
|
||||
MOZ_ASSERT(sNamespace != 0);
|
||||
return static_cast<uint64_t>(sNamespace) << 32;
|
||||
}
|
||||
|
||||
static std::map<std::pair<base::ProcessId, uint64_t>,
|
||||
RefPtr<WebRenderImageHost>>
|
||||
sCompositables;
|
||||
static StaticMutex sMutex MOZ_UNANNOTATED;
|
||||
|
||||
static uint32_t sNamespace;
|
||||
static Atomic<uint32_t> sNextResourceId;
|
||||
static Atomic<uint64_t> sNextHandle;
|
||||
};
|
||||
|
||||
} // namespace mozilla::layers
|
||||
|
|
@ -92,15 +92,14 @@ bool CompositableParentManager::ReceiveCompositableUpdate(
|
|||
op.textureFlags());
|
||||
break;
|
||||
}
|
||||
case CompositableOperationDetail::TOpEnableAsyncCompositable: {
|
||||
const OpEnableAsyncCompositable& op =
|
||||
aDetail.get_OpEnableAsyncCompositable();
|
||||
if (op.enable()) {
|
||||
aCompositable->SetAsyncRef(
|
||||
AsyncCompositableRef(GetChildProcessId(), aHandle));
|
||||
} else {
|
||||
aCompositable->SetAsyncRef(AsyncCompositableRef());
|
||||
}
|
||||
case CompositableOperationDetail::TOpEnableRemoteTexturePushCallback: {
|
||||
const OpEnableRemoteTexturePushCallback& op =
|
||||
aDetail.get_OpEnableRemoteTexturePushCallback();
|
||||
|
||||
aCompositable->SetAsyncRef(
|
||||
AsyncCompositableRef(GetChildProcessId(), aHandle));
|
||||
aCompositable->EnableRemoteTexturePushCallback(
|
||||
op.ownerId(), GetChildProcessId(), op.size(), op.textureFlags());
|
||||
break;
|
||||
}
|
||||
case CompositableOperationDetail::TOpDeliverAcquireFence: {
|
||||
|
|
|
|||
|
|
@ -145,9 +145,16 @@ void ImageBridgeChild::UseRemoteTexture(CompositableClient* aCompositable,
|
|||
OpUseRemoteTexture(aTextureId, aOwnerId, aSize, aFlags)));
|
||||
}
|
||||
|
||||
void ImageBridgeChild::EnableAsyncCompositable(
|
||||
CompositableClient* aCompositable, bool aEnable) {
|
||||
// On ImageBridge, Compositable is always async.
|
||||
void ImageBridgeChild::EnableRemoteTexturePushCallback(
|
||||
CompositableClient* aCompositable, const RemoteTextureOwnerId aOwnerId,
|
||||
const gfx::IntSize aSize, const TextureFlags aFlags) {
|
||||
MOZ_ASSERT(aCompositable);
|
||||
MOZ_ASSERT(aCompositable->GetIPCHandle());
|
||||
MOZ_ASSERT(aCompositable->IsConnected());
|
||||
|
||||
mTxn->AddNoSwapEdit(CompositableOperation(
|
||||
aCompositable->GetIPCHandle(),
|
||||
OpEnableRemoteTexturePushCallback(aOwnerId, aSize, aFlags)));
|
||||
}
|
||||
|
||||
void ImageBridgeChild::HoldUntilCompositableRefReleasedIfNecessary(
|
||||
|
|
|
|||
|
|
@ -251,8 +251,10 @@ class ImageBridgeChild final : public PImageBridgeChild,
|
|||
const gfx::IntSize aSize,
|
||||
const TextureFlags aFlags) override;
|
||||
|
||||
void EnableAsyncCompositable(CompositableClient* aCompositable,
|
||||
bool aEnable) override;
|
||||
void EnableRemoteTexturePushCallback(CompositableClient* aCompositable,
|
||||
const RemoteTextureOwnerId aOwnerId,
|
||||
const gfx::IntSize aSize,
|
||||
const TextureFlags aFlags) override;
|
||||
|
||||
void ReleaseCompositable(const CompositableHandle& aHandle) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ struct ParamTraits<mozilla::layers::CompositableHandleOwner>
|
|||
: public ContiguousEnumSerializerInclusive<
|
||||
mozilla::layers::CompositableHandleOwner,
|
||||
mozilla::layers::CompositableHandleOwner::WebRenderBridge,
|
||||
mozilla::layers::CompositableHandleOwner::InProcessManager> {};
|
||||
mozilla::layers::CompositableHandleOwner::ImageBridge> {};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::layers::RemoteTextureId> {
|
||||
|
|
|
|||
|
|
@ -295,8 +295,10 @@ struct OpUseRemoteTexture {
|
|||
TextureFlags textureFlags;
|
||||
};
|
||||
|
||||
struct OpEnableAsyncCompositable {
|
||||
bool enable;
|
||||
struct OpEnableRemoteTexturePushCallback {
|
||||
RemoteTextureOwnerId ownerId;
|
||||
IntSize size;
|
||||
TextureFlags textureFlags;
|
||||
};
|
||||
|
||||
struct OpNotifyNotUsed {
|
||||
|
|
@ -323,7 +325,7 @@ union CompositableOperationDetail {
|
|||
|
||||
OpUseRemoteTexture;
|
||||
|
||||
OpEnableAsyncCompositable;
|
||||
OpEnableRemoteTexturePushCallback;
|
||||
|
||||
OpDeliverAcquireFence;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ EXPORTS.mozilla.layers += [
|
|||
"ipc/CanvasThread.h",
|
||||
"ipc/CanvasTranslator.h",
|
||||
"ipc/CompositableForwarder.h",
|
||||
"ipc/CompositableInProcessManager.h",
|
||||
"ipc/CompositableTransactionParent.h",
|
||||
"ipc/CompositorBridgeChild.h",
|
||||
"ipc/CompositorBridgeParent.h",
|
||||
|
|
@ -370,7 +369,6 @@ UNIFIED_SOURCES += [
|
|||
"ipc/CanvasThread.cpp",
|
||||
"ipc/CanvasTranslator.cpp",
|
||||
"ipc/CompositableForwarder.cpp",
|
||||
"ipc/CompositableInProcessManager.cpp",
|
||||
"ipc/CompositableTransactionParent.cpp",
|
||||
"ipc/CompositorBench.cpp",
|
||||
"ipc/CompositorBridgeChild.cpp",
|
||||
|
|
|
|||
|
|
@ -462,10 +462,12 @@ void WebRenderBridgeChild::UseRemoteTexture(CompositableClient* aCompositable,
|
|||
OpUseRemoteTexture(aTextureId, aOwnerId, aSize, aFlags)));
|
||||
}
|
||||
|
||||
void WebRenderBridgeChild::EnableAsyncCompositable(
|
||||
CompositableClient* aCompositable, bool aEnable) {
|
||||
void WebRenderBridgeChild::EnableRemoteTexturePushCallback(
|
||||
CompositableClient* aCompositable, const RemoteTextureOwnerId aOwnerId,
|
||||
const gfx::IntSize aSize, const TextureFlags aFlags) {
|
||||
AddWebRenderParentCommand(CompositableOperation(
|
||||
aCompositable->GetIPCHandle(), OpEnableAsyncCompositable(aEnable)));
|
||||
aCompositable->GetIPCHandle(),
|
||||
OpEnableRemoteTexturePushCallback(aOwnerId, aSize, aFlags)));
|
||||
}
|
||||
|
||||
void WebRenderBridgeChild::UpdateFwdTransactionId() {
|
||||
|
|
|
|||
|
|
@ -205,8 +205,10 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild,
|
|||
const RemoteTextureOwnerId aOwnerId,
|
||||
const gfx::IntSize aSize,
|
||||
const TextureFlags aFlags) override;
|
||||
void EnableAsyncCompositable(CompositableClient* aCompositable,
|
||||
bool aEnable) override;
|
||||
void EnableRemoteTexturePushCallback(CompositableClient* aCompositable,
|
||||
const RemoteTextureOwnerId aOwnerId,
|
||||
const gfx::IntSize aSize,
|
||||
const TextureFlags aFlags) override;
|
||||
void UpdateFwdTransactionId() override;
|
||||
uint64_t GetFwdTransactionId() override;
|
||||
bool InForwarderThread() override;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include "mozilla/layers/AnimationHelper.h"
|
||||
#include "mozilla/layers/APZSampler.h"
|
||||
#include "mozilla/layers/APZUpdater.h"
|
||||
#include "mozilla/layers/CompositableInProcessManager.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorAnimationStorage.h"
|
||||
|
|
@ -1771,9 +1770,6 @@ void WebRenderBridgeParent::AddPipelineIdForCompositable(
|
|||
host = imageBridge->FindCompositable(aHandle);
|
||||
break;
|
||||
}
|
||||
case CompositableHandleOwner::InProcessManager:
|
||||
host = CompositableInProcessManager::Find(aHandle, OtherPid());
|
||||
break;
|
||||
}
|
||||
|
||||
if (!host) {
|
||||
|
|
|
|||
|
|
@ -2262,24 +2262,6 @@ bool WebRenderCommandBuilder::PushImageProvider(
|
|||
return true;
|
||||
}
|
||||
|
||||
void WebRenderCommandBuilder::PushInProcessImage(
|
||||
nsDisplayItem* aItem, const CompositableHandle& aHandle,
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
const LayoutDeviceRect& aAsyncImageBounds) {
|
||||
RefPtr<WebRenderInProcessImageData> imageData =
|
||||
CreateOrRecycleWebRenderUserData<WebRenderInProcessImageData>(aItem);
|
||||
MOZ_ASSERT(imageData);
|
||||
|
||||
auto rendering = wr::ToImageRendering(aItem->Frame()->UsedImageRendering());
|
||||
LayoutDeviceRect scBounds(LayoutDevicePoint(0, 0), aAsyncImageBounds.Size());
|
||||
imageData->CreateWebRenderCommands(aBuilder, aHandle, aSc, aAsyncImageBounds,
|
||||
scBounds, VideoInfo::Rotation::kDegree_0,
|
||||
rendering, wr::MixBlendMode::Normal,
|
||||
!aItem->BackfaceIsHidden());
|
||||
}
|
||||
|
||||
static void PaintItemByDrawTarget(nsDisplayItem* aItem, gfx::DrawTarget* aDT,
|
||||
const LayoutDevicePoint& aOffset,
|
||||
const IntRect& visibleRect,
|
||||
|
|
|
|||
|
|
@ -92,13 +92,6 @@ class WebRenderCommandBuilder final {
|
|||
const LayoutDeviceRect& aRect,
|
||||
const LayoutDeviceRect& aClip);
|
||||
|
||||
void PushInProcessImage(nsDisplayItem* aItem,
|
||||
const CompositableHandle& aHandle,
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
const LayoutDeviceRect& aAsyncImageBounds);
|
||||
|
||||
Maybe<wr::ImageMask> BuildWrMaskImage(
|
||||
nsDisplayMasksAndClipPaths* aMaskItem, wr::DisplayListBuilder& aBuilder,
|
||||
wr::IpcResourceUpdateQueue& aResources, const StackingContextHelper& aSc,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,14 @@ WebRenderImageHost::~WebRenderImageHost() {
|
|||
}
|
||||
|
||||
void WebRenderImageHost::OnReleased() {
|
||||
if (mRemoteTextureOwnerIdOfPushCallback) {
|
||||
RemoteTextureMap::Get()->UnregisterRemoteTexturePushListener(
|
||||
*mRemoteTextureOwnerIdOfPushCallback, mForPidOfPushCallback, this);
|
||||
mRemoteTextureOwnerIdOfPushCallback = Nothing();
|
||||
mSizeOfPushCallback = gfx::IntSize();
|
||||
mFlagsOfPushCallback = TextureFlags::NO_FLAGS;
|
||||
}
|
||||
|
||||
if (mRemoteTextureHost) {
|
||||
mRemoteTextureHost = nullptr;
|
||||
}
|
||||
|
|
@ -138,6 +146,40 @@ void WebRenderImageHost::UseRemoteTexture(const RemoteTextureId aTextureId,
|
|||
}
|
||||
}
|
||||
|
||||
void WebRenderImageHost::EnableRemoteTexturePushCallback(
|
||||
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
|
||||
const gfx::IntSize aSize, const TextureFlags aFlags) {
|
||||
if (!GetAsyncRef()) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRemoteTextureOwnerIdOfPushCallback.isSome()) {
|
||||
RemoteTextureMap::Get()->UnregisterRemoteTexturePushListener(aOwnerId,
|
||||
aForPid, this);
|
||||
}
|
||||
|
||||
RemoteTextureMap::Get()->RegisterRemoteTexturePushListener(aOwnerId, aForPid,
|
||||
this);
|
||||
mRemoteTextureOwnerIdOfPushCallback = Some(aOwnerId);
|
||||
mForPidOfPushCallback = aForPid;
|
||||
mSizeOfPushCallback = aSize;
|
||||
mFlagsOfPushCallback = aFlags;
|
||||
}
|
||||
|
||||
void WebRenderImageHost::NotifyPushTexture(const RemoteTextureId aTextureId,
|
||||
const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
if (mRemoteTextureOwnerIdOfPushCallback != Some(aOwnerId)) {
|
||||
// RemoteTextureOwnerId is already obsoleted
|
||||
return;
|
||||
}
|
||||
UseRemoteTexture(aTextureId, aOwnerId, aForPid, mSizeOfPushCallback,
|
||||
mFlagsOfPushCallback);
|
||||
}
|
||||
|
||||
void WebRenderImageHost::CleanupResources() {
|
||||
ClearImages();
|
||||
SetCurrentTextureHost(nullptr);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,15 @@ class WebRenderImageHost : public CompositableHost, public ImageComposite {
|
|||
const TextureFlags aFlags) override;
|
||||
void RemoveTextureHost(TextureHost* aTexture) override;
|
||||
|
||||
void EnableRemoteTexturePushCallback(const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid,
|
||||
const gfx::IntSize aSize,
|
||||
const TextureFlags aFlags) override;
|
||||
|
||||
void NotifyPushTexture(const RemoteTextureId aTextureId,
|
||||
const RemoteTextureOwnerId aOwnerId,
|
||||
const base::ProcessId aForPid) override;
|
||||
|
||||
void Dump(std::stringstream& aStream, const char* aPrefix = "",
|
||||
bool aDumpHtml = false) override;
|
||||
|
||||
|
|
@ -73,6 +82,11 @@ class WebRenderImageHost : public CompositableHost, public ImageComposite {
|
|||
CompositableTextureHostRef mCurrentTextureHost;
|
||||
|
||||
CompositableTextureHostRef mRemoteTextureHost;
|
||||
|
||||
Maybe<RemoteTextureOwnerId> mRemoteTextureOwnerIdOfPushCallback;
|
||||
base::ProcessId mForPidOfPushCallback;
|
||||
gfx::IntSize mSizeOfPushCallback;
|
||||
TextureFlags mFlagsOfPushCallback = TextureFlags::NO_FLAGS;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
|||
|
|
@ -287,60 +287,6 @@ bool WebRenderImageProviderData::Invalidate(ImageProviderId aProviderId) const {
|
|||
return NS_SUCCEEDED(rv) && mKey.ref() == key;
|
||||
}
|
||||
|
||||
WebRenderInProcessImageData::WebRenderInProcessImageData(
|
||||
RenderRootStateManager* aManager, nsDisplayItem* aItem)
|
||||
: WebRenderUserData(aManager, aItem) {}
|
||||
|
||||
WebRenderInProcessImageData::WebRenderInProcessImageData(
|
||||
RenderRootStateManager* aManager, uint32_t aDisplayItemKey,
|
||||
nsIFrame* aFrame)
|
||||
: WebRenderUserData(aManager, aDisplayItemKey, aFrame) {}
|
||||
|
||||
WebRenderInProcessImageData::~WebRenderInProcessImageData() {
|
||||
if (mPipelineId) {
|
||||
mManager->RemovePipelineIdForCompositable(mPipelineId.ref());
|
||||
}
|
||||
}
|
||||
|
||||
void WebRenderInProcessImageData::CreateWebRenderCommands(
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
const CompositableHandle& aHandle, const StackingContextHelper& aSc,
|
||||
const LayoutDeviceRect& aBounds, const LayoutDeviceRect& aSCBounds,
|
||||
VideoInfo::Rotation aRotation, const wr::ImageRendering& aFilter,
|
||||
const wr::MixBlendMode& aMixBlendMode, bool aIsBackfaceVisible) {
|
||||
MOZ_ASSERT(aHandle);
|
||||
|
||||
if (mPipelineId.isSome() && !(mHandle == aHandle)) {
|
||||
// In this case, we need to remove the existed pipeline and create new one
|
||||
// because the CompositableHandle has changed.
|
||||
WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
|
||||
mPipelineId.reset();
|
||||
}
|
||||
|
||||
if (!mPipelineId) {
|
||||
// Alloc in process image pipeline id.
|
||||
mPipelineId =
|
||||
Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
|
||||
WrBridge()->AddPipelineIdForCompositable(
|
||||
mPipelineId.ref(), aHandle, CompositableHandleOwner::InProcessManager);
|
||||
mHandle = aHandle;
|
||||
}
|
||||
|
||||
// Push IFrame for in process image pipeline.
|
||||
//
|
||||
// We don't push a stacking context for this in process image pipeline here.
|
||||
// Instead, we do it inside the iframe that hosts the image. As a result,
|
||||
// a bunch of the calculations normally done as part of that stacking
|
||||
// context need to be done manually and pushed over to the parent side,
|
||||
// where it will be done when we build the display list for the iframe.
|
||||
// That happens in AsyncImagePipelineManager.
|
||||
aBuilder.PushIFrame(aBounds, aIsBackfaceVisible, mPipelineId.ref(),
|
||||
/*ignoreMissingPipelines*/ false);
|
||||
|
||||
WrBridge()->AddWebRenderParentCommand(OpUpdateAsyncImagePipeline(
|
||||
mPipelineId.value(), aSCBounds, aRotation, aFilter, aMixBlendMode));
|
||||
}
|
||||
|
||||
WebRenderFallbackData::WebRenderFallbackData(RenderRootStateManager* aManager,
|
||||
nsDisplayItem* aItem)
|
||||
: WebRenderUserData(aManager, aItem), mOpacity(1.0f), mInvalid(false) {}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ class WebRenderCanvasRenderer;
|
|||
class WebRenderCanvasRendererAsync;
|
||||
class WebRenderImageData;
|
||||
class WebRenderImageProviderData;
|
||||
class WebRenderInProcessImageData;
|
||||
class WebRenderFallbackData;
|
||||
class RenderRootStateManager;
|
||||
class WebRenderGroupData;
|
||||
|
|
@ -84,9 +83,6 @@ class WebRenderUserData {
|
|||
|
||||
virtual WebRenderImageData* AsImageData() { return nullptr; }
|
||||
virtual WebRenderImageProviderData* AsImageProviderData() { return nullptr; }
|
||||
virtual WebRenderInProcessImageData* AsInProcessImageData() {
|
||||
return nullptr;
|
||||
}
|
||||
virtual WebRenderFallbackData* AsFallbackData() { return nullptr; }
|
||||
virtual WebRenderCanvasData* AsCanvasData() { return nullptr; }
|
||||
virtual WebRenderGroupData* AsGroupData() { return nullptr; }
|
||||
|
|
@ -213,30 +209,6 @@ class WebRenderImageProviderData final : public WebRenderUserData {
|
|||
image::ImgDrawResult mDrawResult = image::ImgDrawResult::NOT_READY;
|
||||
};
|
||||
|
||||
class WebRenderInProcessImageData final : public WebRenderUserData {
|
||||
public:
|
||||
WebRenderInProcessImageData(RenderRootStateManager* aManager,
|
||||
nsDisplayItem* aItem);
|
||||
WebRenderInProcessImageData(RenderRootStateManager* aManager,
|
||||
uint32_t aDisplayItemKey, nsIFrame* aFrame);
|
||||
~WebRenderInProcessImageData() override;
|
||||
|
||||
WebRenderInProcessImageData* AsInProcessImageData() override { return this; }
|
||||
UserDataType GetType() override { return UserDataType::eInProcessImage; }
|
||||
static UserDataType Type() { return UserDataType::eInProcessImage; }
|
||||
|
||||
void CreateWebRenderCommands(
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
const CompositableHandle& aHandle, const StackingContextHelper& aSc,
|
||||
const LayoutDeviceRect& aBounds, const LayoutDeviceRect& aSCBounds,
|
||||
VideoInfo::Rotation aRotation, const wr::ImageRendering& aFilter,
|
||||
const wr::MixBlendMode& aMixBlendMode, bool aIsBackfaceVisible);
|
||||
|
||||
protected:
|
||||
Maybe<wr::PipelineId> mPipelineId;
|
||||
CompositableHandle mHandle = CompositableHandle();
|
||||
};
|
||||
|
||||
/// Used for fallback rendering.
|
||||
///
|
||||
/// In most cases this uses blob images but it can also render on the content
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include "mozilla/gfx/GPUParent.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "mozilla/layers/CompositableInProcessManager.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorManagerParent.h"
|
||||
|
|
@ -131,7 +130,6 @@ void RenderThread::Start(uint32_t aNamespace) {
|
|||
#ifdef XP_WIN
|
||||
widget::WinCompositorWindowThread::Start();
|
||||
#endif
|
||||
layers::CompositableInProcessManager::Initialize(aNamespace);
|
||||
layers::SharedSurfacesParent::Initialize();
|
||||
|
||||
RefPtr<Runnable> runnable = WrapRunnable(
|
||||
|
|
@ -159,7 +157,6 @@ void RenderThread::ShutDown() {
|
|||
oldThread->Shutdown();
|
||||
|
||||
layers::SharedSurfacesParent::Shutdown();
|
||||
layers::CompositableInProcessManager::Shutdown();
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (widget::WinCompositorWindowThread::Get()) {
|
||||
|
|
|
|||
|
|
@ -124,25 +124,20 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem {
|
|||
|
||||
RefPtr<ImageContainer> container = element->GetImageContainer();
|
||||
if (container) {
|
||||
MOZ_ASSERT(container->IsAsync());
|
||||
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;
|
||||
}
|
||||
|
||||
switch (element->GetCurrentContextType()) {
|
||||
case CanvasContextType::Canvas2D:
|
||||
case CanvasContextType::WebGL1:
|
||||
case CanvasContextType::WebGL2: {
|
||||
case CanvasContextType::WebGL2:
|
||||
case CanvasContextType::WebGPU: {
|
||||
bool isRecycled;
|
||||
RefPtr<WebRenderCanvasData> canvasData =
|
||||
aManager->CommandBuilder()
|
||||
|
|
@ -194,33 +189,6 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem {
|
|||
mixBlendMode));
|
||||
break;
|
||||
}
|
||||
case CanvasContextType::WebGPU: {
|
||||
nsHTMLCanvasFrame* canvasFrame =
|
||||
static_cast<nsHTMLCanvasFrame*>(mFrame);
|
||||
HTMLCanvasElement* canvasElement =
|
||||
static_cast<HTMLCanvasElement*>(canvasFrame->GetContent());
|
||||
webgpu::CanvasContext* canvasContext =
|
||||
canvasElement->GetWebGPUContext();
|
||||
|
||||
if (!canvasContext || !canvasContext->mHandle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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().PushInProcessImage(
|
||||
this, canvasContext->mHandle, aBuilder, aResources, aSc, bounds);
|
||||
break;
|
||||
}
|
||||
case CanvasContextType::ImageBitmap: {
|
||||
nsHTMLCanvasFrame* canvasFrame =
|
||||
static_cast<nsHTMLCanvasFrame*>(mFrame);
|
||||
|
|
|
|||
Loading…
Reference in a new issue