mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Bug 1464032 Part 12: Add CanvasParent, CanvasChild and RecordedTextureData. r=mattwoodrow, jld
RecordedTextureData records TextureData calls for play back in the GPU process. CanvasChild and CanvasParent set up the recorder and translator. They also help to manage the starting of translation and co-ordinating the translation with the frame transactions. This patch also includes other changes to wire up recording and playback.
This commit is contained in:
parent
2853ef8068
commit
387477fb68
@ -1611,19 +1611,13 @@ UniquePtr<uint8_t[]> CanvasRenderingContext2D::GetImageBuffer(
|
||||
|
||||
*aFormat = 0;
|
||||
|
||||
RefPtr<SourceSurface> snapshot;
|
||||
if (mTarget) {
|
||||
snapshot = mTarget->Snapshot();
|
||||
} else if (mBufferProvider) {
|
||||
snapshot = mBufferProvider->BorrowSnapshot();
|
||||
} else {
|
||||
EnsureTarget();
|
||||
if (!IsTargetValid()) {
|
||||
if (!mBufferProvider) {
|
||||
if (!EnsureTarget()) {
|
||||
return nullptr;
|
||||
}
|
||||
snapshot = mTarget->Snapshot();
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> snapshot = mBufferProvider->BorrowSnapshot();
|
||||
if (snapshot) {
|
||||
RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
|
||||
if (data && data->GetSize() == GetSize()) {
|
||||
@ -1632,9 +1626,7 @@ UniquePtr<uint8_t[]> CanvasRenderingContext2D::GetImageBuffer(
|
||||
}
|
||||
}
|
||||
|
||||
if (!mTarget && mBufferProvider) {
|
||||
mBufferProvider->ReturnSnapshot(snapshot.forget());
|
||||
}
|
||||
mBufferProvider->ReturnSnapshot(snapshot.forget());
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1672,6 +1664,29 @@ CanvasRenderingContext2D::GetInputStream(const char* aMimeType,
|
||||
aStream);
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::gfx::SourceSurface>
|
||||
CanvasRenderingContext2D::GetSurfaceSnapshot(gfxAlphaType* aOutAlphaType) {
|
||||
if (!mBufferProvider) {
|
||||
if (!EnsureTarget()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> snapshot = mBufferProvider->BorrowSnapshot();
|
||||
if (!snapshot) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurface = snapshot->GetDataSurface();
|
||||
mBufferProvider->ReturnSnapshot(snapshot.forget());
|
||||
|
||||
if (aOutAlphaType) {
|
||||
*aOutAlphaType = (mOpaque ? gfxAlphaType::Opaque : gfxAlphaType::Premult);
|
||||
}
|
||||
|
||||
return dataSurface.forget();
|
||||
}
|
||||
|
||||
SurfaceFormat CanvasRenderingContext2D::GetSurfaceFormat() const {
|
||||
return mOpaque ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;
|
||||
}
|
||||
@ -4920,27 +4935,21 @@ nsresult CanvasRenderingContext2D::GetImageDataArray(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> readback;
|
||||
DataSourceSurface::MappedSurface rawData;
|
||||
RefPtr<SourceSurface> snapshot;
|
||||
if (!mTarget && mBufferProvider) {
|
||||
snapshot = mBufferProvider->BorrowSnapshot();
|
||||
} else {
|
||||
EnsureTarget();
|
||||
if (!IsTargetValid()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!mBufferProvider) {
|
||||
if (!EnsureTarget()) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
snapshot = mTarget->Snapshot();
|
||||
}
|
||||
|
||||
if (snapshot) {
|
||||
readback = snapshot->GetDataSurface();
|
||||
RefPtr<SourceSurface> snapshot = mBufferProvider->BorrowSnapshot();
|
||||
if (!snapshot) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!mTarget && mBufferProvider) {
|
||||
mBufferProvider->ReturnSnapshot(snapshot.forget());
|
||||
}
|
||||
RefPtr<DataSourceSurface> readback = snapshot->GetDataSurface();
|
||||
mBufferProvider->ReturnSnapshot(snapshot.forget());
|
||||
|
||||
DataSourceSurface::MappedSurface rawData;
|
||||
if (!readback || !readback->Map(DataSourceSurface::READ, &rawData)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -409,13 +409,7 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal,
|
||||
nsIInputStream** aStream) override;
|
||||
|
||||
already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(
|
||||
gfxAlphaType* aOutAlphaType = nullptr) override {
|
||||
EnsureTarget();
|
||||
if (aOutAlphaType) {
|
||||
*aOutAlphaType = (mOpaque ? gfxAlphaType::Opaque : gfxAlphaType::Premult);
|
||||
}
|
||||
return mTarget->Snapshot();
|
||||
}
|
||||
gfxAlphaType* aOutAlphaType = nullptr) override;
|
||||
|
||||
virtual void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) override;
|
||||
bool GetIsOpaque() override { return mOpaque; }
|
||||
|
@ -425,13 +425,18 @@ TextureClient* PersistentBufferProviderShared::GetTextureClient() {
|
||||
|
||||
already_AddRefed<gfx::SourceSurface>
|
||||
PersistentBufferProviderShared::BorrowSnapshot() {
|
||||
MOZ_ASSERT(!mDrawTarget);
|
||||
|
||||
if (mPreviousSnapshot) {
|
||||
mSnapshot = mPreviousSnapshot;
|
||||
return do_AddRef(mSnapshot);
|
||||
}
|
||||
|
||||
if (mDrawTarget) {
|
||||
auto back = GetTexture(mBack);
|
||||
MOZ_ASSERT(back && back->IsLocked());
|
||||
mSnapshot = back->BorrowSnapshot();
|
||||
return do_AddRef(mSnapshot);
|
||||
}
|
||||
|
||||
auto front = GetTexture(mFront);
|
||||
if (!front || front->IsLocked()) {
|
||||
MOZ_ASSERT(false);
|
||||
@ -455,7 +460,7 @@ void PersistentBufferProviderShared::ReturnSnapshot(
|
||||
mSnapshot = nullptr;
|
||||
snapshot = nullptr;
|
||||
|
||||
if (mPreviousSnapshot) {
|
||||
if (mPreviousSnapshot || mDrawTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -665,6 +665,8 @@ void ClientLayerManager::ForwardTransaction(bool aScheduleComposite) {
|
||||
AUTO_PROFILER_TRACING("Paint", "ForwardTransaction", GRAPHICS);
|
||||
TimeStamp start = TimeStamp::Now();
|
||||
|
||||
GetCompositorBridgeChild()->EndCanvasTransaction();
|
||||
|
||||
// Skip the synchronization for buffer since we also skip the painting during
|
||||
// device-reset status. With OMTP, we have to wait for async paints
|
||||
// before we synchronize and it's done on the paint thread.
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/PaintThread.h"
|
||||
#include "mozilla/layers/TextureClientRecycleAllocator.h"
|
||||
#include "mozilla/layers/TextureRecorded.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
||||
@ -343,7 +344,11 @@ TextureData::Create(TextureForwarder* aAllocator, gfx::SurfaceFormat aFormat,
|
||||
aAllocFlags);
|
||||
|
||||
if (ShouldRemoteTextureType(textureType, aSelector)) {
|
||||
// TODO: return a recording texture data here.
|
||||
RefPtr<CanvasChild> canvasChild = aAllocator->GetCanvasChild();
|
||||
if (canvasChild) {
|
||||
return new RecordedTextureData(canvasChild.forget(), aSize, aFormat,
|
||||
textureType);
|
||||
}
|
||||
}
|
||||
|
||||
switch(textureType) {
|
||||
|
110
gfx/layers/client/TextureRecorded.cpp
Normal file
110
gfx/layers/client/TextureRecorded.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "TextureRecorded.h"
|
||||
|
||||
#include "RecordedCanvasEventImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceCanvasRecording, final)
|
||||
|
||||
SourceSurfaceCanvasRecording(RefPtr<gfx::SourceSurface>& aRecordedSuface,
|
||||
RefPtr<CanvasChild>& aCanvasChild)
|
||||
: mRecordedSurface(aRecordedSuface), mCanvasChild(aCanvasChild) {}
|
||||
|
||||
gfx::SurfaceType GetType() const final { return mRecordedSurface->GetType(); }
|
||||
|
||||
gfx::IntSize GetSize() const final { return mRecordedSurface->GetSize(); }
|
||||
|
||||
gfx::SurfaceFormat GetFormat() const final {
|
||||
return mRecordedSurface->GetFormat();
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetDataSurface() final {
|
||||
if (!mDataSourceSurface) {
|
||||
mDataSourceSurface = mCanvasChild->GetDataSurface(mRecordedSurface);
|
||||
}
|
||||
|
||||
return do_AddRef(mDataSourceSurface);
|
||||
}
|
||||
|
||||
RefPtr<gfx::SourceSurface> mRecordedSurface;
|
||||
RefPtr<CanvasChild> mCanvasChild;
|
||||
RefPtr<gfx::DataSourceSurface> mDataSourceSurface;
|
||||
};
|
||||
|
||||
RecordedTextureData::RecordedTextureData(
|
||||
already_AddRefed<CanvasChild> aCanvasChild, gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat, TextureType aTextureType)
|
||||
: mCanvasChild(aCanvasChild), mSize(aSize), mFormat(aFormat) {
|
||||
mCanvasChild->EnsureRecorder(aTextureType);
|
||||
}
|
||||
|
||||
RecordedTextureData::~RecordedTextureData() {}
|
||||
|
||||
void RecordedTextureData::FillInfo(TextureData::Info& aInfo) const {
|
||||
aInfo.size = mSize;
|
||||
aInfo.format = mFormat;
|
||||
aInfo.supportsMoz2D = true;
|
||||
aInfo.hasIntermediateBuffer = false;
|
||||
aInfo.hasSynchronization = true;
|
||||
}
|
||||
|
||||
bool RecordedTextureData::Lock(OpenMode aMode) {
|
||||
mCanvasChild->EnsureBeginTransaction();
|
||||
if (!mDT) {
|
||||
mDT = mCanvasChild->CreateDrawTarget(mSize, mFormat);
|
||||
|
||||
// We lock the TextureData when we create it to get the remote DrawTarget.
|
||||
mCanvasChild->OnTextureWriteLock();
|
||||
return true;
|
||||
}
|
||||
|
||||
mCanvasChild->RecordEvent(RecordedTextureLock(mDT.get(), aMode));
|
||||
if (aMode & OpenMode::OPEN_WRITE) {
|
||||
mCanvasChild->OnTextureWriteLock();
|
||||
mSnapshot = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RecordedTextureData::Unlock() {
|
||||
mCanvasChild->RecordEvent(RecordedTextureUnlock(mDT.get()));
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> RecordedTextureData::BorrowDrawTarget() {
|
||||
return do_AddRef(mDT);
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::SourceSurface> RecordedTextureData::BorrowSnapshot() {
|
||||
MOZ_ASSERT(mDT);
|
||||
|
||||
mSnapshot = mDT->Snapshot();
|
||||
return MakeAndAddRef<SourceSurfaceCanvasRecording>(mSnapshot, mCanvasChild);
|
||||
}
|
||||
|
||||
void RecordedTextureData::Deallocate(LayersIPCChannel* aAllocator) {}
|
||||
|
||||
bool RecordedTextureData::Serialize(SurfaceDescriptor& aDescriptor) {
|
||||
SurfaceDescriptorRecorded descriptor;
|
||||
descriptor.drawTarget() = reinterpret_cast<uintptr_t>(mDT.get());
|
||||
aDescriptor = std::move(descriptor);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RecordedTextureData::OnForwardedToHost() {
|
||||
mCanvasChild->OnTextureForwarded();
|
||||
if (mSnapshot && mCanvasChild->ShouldCacheDataSurface()) {
|
||||
mCanvasChild->RecordEvent(RecordedCacheDataSurface(mSnapshot.get()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
53
gfx/layers/client/TextureRecorded.h
Normal file
53
gfx/layers/client/TextureRecorded.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_layers_TextureRecorded_h
|
||||
#define mozilla_layers_TextureRecorded_h
|
||||
|
||||
#include "TextureClient.h"
|
||||
#include "mozilla/layers/CanvasChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class RecordedTextureData final : public TextureData {
|
||||
public:
|
||||
RecordedTextureData(already_AddRefed<CanvasChild> aCanvasChild,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureType aTextureType);
|
||||
|
||||
void FillInfo(TextureData::Info& aInfo) const final;
|
||||
|
||||
bool Lock(OpenMode aMode) final;
|
||||
|
||||
void Unlock() final;
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() final;
|
||||
|
||||
already_AddRefed<gfx::SourceSurface> BorrowSnapshot() final;
|
||||
|
||||
void Deallocate(LayersIPCChannel* aAllocator) final;
|
||||
|
||||
bool Serialize(SurfaceDescriptor& aDescriptor) final;
|
||||
|
||||
void OnForwardedToHost() final;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(RecordedTextureData);
|
||||
|
||||
~RecordedTextureData() override;
|
||||
|
||||
RefPtr<CanvasChild> mCanvasChild;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
RefPtr<gfx::DrawTarget> mDT;
|
||||
RefPtr<gfx::SourceSurface> mSnapshot;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_TextureRecorded_h
|
@ -216,6 +216,16 @@ already_AddRefed<TextureHost> TextureHost::Create(
|
||||
result = CreateTextureHostD3D11(aDesc, aDeallocator, aBackend, aFlags);
|
||||
break;
|
||||
#endif
|
||||
case SurfaceDescriptor::TSurfaceDescriptorRecorded: {
|
||||
const SurfaceDescriptorRecorded& desc =
|
||||
aDesc.get_SurfaceDescriptorRecorded();
|
||||
UniquePtr<SurfaceDescriptor> realDesc =
|
||||
aDeallocator->AsCompositorBridgeParentBase()
|
||||
->LookupSurfaceDescriptorForClientDrawTarget(desc.drawTarget());
|
||||
result = TextureHost::Create(*realDesc, aReadLock, aDeallocator, aBackend,
|
||||
aFlags, aExternalImageId);
|
||||
return result.forget();
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("GFX: Unsupported Surface type host");
|
||||
}
|
||||
|
@ -728,7 +728,8 @@ already_AddRefed<TextureHost> CreateTextureHostD3D11(
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget> D3D11TextureData::BorrowDrawTarget() {
|
||||
MOZ_ASSERT(NS_IsMainThread() || PaintThread::IsOnPaintThread());
|
||||
MOZ_ASSERT(NS_IsMainThread() || PaintThread::IsOnPaintThread() ||
|
||||
NS_IsInCanvasThread());
|
||||
|
||||
if (!mDrawTarget && mTexture) {
|
||||
// This may return a null DrawTarget
|
||||
|
150
gfx/layers/ipc/CanvasChild.cpp
Normal file
150
gfx/layers/ipc/CanvasChild.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "CanvasChild.h"
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/gfx/DrawTargetRecording.h"
|
||||
#include "mozilla/gfx/Tools.h"
|
||||
#include "mozilla/layers/CanvasDrawEventRecorder.h"
|
||||
#include "RecordedCanvasEventImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static const TimeDuration kLockWaitTimeout =
|
||||
TimeDuration::FromMilliseconds(100);
|
||||
static const TimeDuration kGetDataTimeout = TimeDuration::FromMilliseconds(500);
|
||||
|
||||
CanvasChild::CanvasChild(Endpoint<PCanvasChild>&& aEndpoint) {
|
||||
aEndpoint.Bind(this);
|
||||
mCanSend = true;
|
||||
}
|
||||
|
||||
CanvasChild::~CanvasChild() {}
|
||||
|
||||
void CanvasChild::EnsureRecorder(TextureType aTextureType) {
|
||||
if (!mRecorder) {
|
||||
MOZ_ASSERT(mTextureType == TextureType::Unknown);
|
||||
mTextureType = aTextureType;
|
||||
mRecorder = MakeAndAddRef<CanvasDrawEventRecorder>();
|
||||
SharedMemoryBasic::Handle handle;
|
||||
CrossProcessSemaphoreHandle readerSem;
|
||||
CrossProcessSemaphoreHandle writerSem;
|
||||
RefPtr<CanvasChild> thisRef = this;
|
||||
mRecorder->Init(OtherPid(), &handle, &readerSem, &writerSem,
|
||||
[cc = std::move(thisRef)] { cc->ResumeTranslation(); });
|
||||
|
||||
if (mCanSend) {
|
||||
Unused << SendCreateTranslator(mTextureType, handle, readerSem,
|
||||
writerSem);
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(mTextureType == aTextureType,
|
||||
"We only support one remote TextureType currently.");
|
||||
}
|
||||
|
||||
void CanvasChild::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
mCanSend = false;
|
||||
|
||||
// Explicitly drop our reference to the recorder, because it holds a reference
|
||||
// to us via the ResumeTranslation callback.
|
||||
mRecorder = nullptr;
|
||||
}
|
||||
|
||||
void CanvasChild::ResumeTranslation() {
|
||||
if (mCanSend) {
|
||||
SendResumeTranslation();
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasChild::Destroy() { Close(); }
|
||||
|
||||
void CanvasChild::OnTextureWriteLock() {
|
||||
mHasOutstandingWriteLock = true;
|
||||
mLastWriteLockCheckpoint = mRecorder->CreateCheckpoint();
|
||||
}
|
||||
|
||||
void CanvasChild::OnTextureForwarded() {
|
||||
if (mHasOutstandingWriteLock) {
|
||||
mRecorder->RecordEvent(RecordedCanvasFlush());
|
||||
if (!mRecorder->WaitForCheckpoint(mLastWriteLockCheckpoint,
|
||||
kLockWaitTimeout)) {
|
||||
gfxWarning() << "Timed out waiting for last write lock to be processed.";
|
||||
}
|
||||
|
||||
mHasOutstandingWriteLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasChild::EnsureBeginTransaction() {
|
||||
if (!mIsInTransaction) {
|
||||
mRecorder->RecordEvent(RecordedCanvasBeginTransaction());
|
||||
mIsInTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasChild::EndTransaction() {
|
||||
if (mIsInTransaction) {
|
||||
mRecorder->RecordEvent(RecordedCanvasEndTransaction());
|
||||
mIsInTransaction = false;
|
||||
}
|
||||
|
||||
++mTransactionsSinceGetDataSurface;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> CanvasChild::CreateDrawTarget(
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat) {
|
||||
MOZ_ASSERT(mRecorder);
|
||||
|
||||
RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(
|
||||
gfx::BackendType::SKIA, gfx::IntSize(1, 1), aFormat);
|
||||
RefPtr<gfx::DrawTarget> dt =
|
||||
MakeAndAddRef<gfx::DrawTargetRecording>(mRecorder, dummyDt, aSize);
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
void CanvasChild::RecordEvent(const gfx::RecordedEvent& aEvent) {
|
||||
mRecorder->RecordEvent(aEvent);
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
|
||||
const gfx::SourceSurface* aSurface) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aSurface);
|
||||
|
||||
mTransactionsSinceGetDataSurface = 0;
|
||||
EnsureBeginTransaction();
|
||||
mRecorder->RecordEvent(RecordedPrepareDataForSurface(aSurface));
|
||||
uint32_t checkpoint = mRecorder->CreateCheckpoint();
|
||||
|
||||
gfx::IntSize ssSize = aSurface->GetSize();
|
||||
gfx::SurfaceFormat ssFormat = aSurface->GetFormat();
|
||||
size_t dataFormatWidth = ssSize.width * BytesPerPixel(ssFormat);
|
||||
RefPtr<gfx::DataSourceSurface> dataSurface =
|
||||
gfx::Factory::CreateDataSourceSurfaceWithStride(ssSize, ssFormat,
|
||||
dataFormatWidth);
|
||||
if (!dataSurface) {
|
||||
gfxWarning() << "Failed to create DataSourceSurface.";
|
||||
return nullptr;
|
||||
}
|
||||
gfx::DataSourceSurface::ScopedMap map(dataSurface,
|
||||
gfx::DataSourceSurface::READ_WRITE);
|
||||
char* dest = reinterpret_cast<char*>(map.GetData());
|
||||
if (!mRecorder->WaitForCheckpoint(checkpoint, kGetDataTimeout)) {
|
||||
gfxWarning() << "Timed out preparing data for DataSourceSurface.";
|
||||
return dataSurface.forget();
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedGetDataForSurface(aSurface));
|
||||
mRecorder->ReturnRead(dest, ssSize.height * dataFormatWidth);
|
||||
|
||||
return dataSurface.forget();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
117
gfx/layers/ipc/CanvasChild.h
Normal file
117
gfx/layers/ipc/CanvasChild.h
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_layers_CanvasChild_h
|
||||
#define mozilla_layers_CanvasChild_h
|
||||
|
||||
#include "mozilla/gfx/RecordedEvent.h"
|
||||
#include "mozilla/ipc/CrossProcessSemaphore.h"
|
||||
#include "mozilla/layers/PCanvasChild.h"
|
||||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
class CanvasDrawEventRecorder;
|
||||
|
||||
class CanvasChild final : public PCanvasChild {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(CanvasChild)
|
||||
|
||||
explicit CanvasChild(Endpoint<PCanvasChild>&& aEndpoint);
|
||||
|
||||
/**
|
||||
* Ensures that the DrawEventRecorder has been created.
|
||||
*
|
||||
* @params aTextureType the TextureType to create in the CanvasTranslator.
|
||||
*/
|
||||
void EnsureRecorder(TextureType aTextureType);
|
||||
|
||||
/**
|
||||
* Send a messsage to our CanvasParent to resume translation.
|
||||
*/
|
||||
void ResumeTranslation();
|
||||
|
||||
/**
|
||||
* Clean up IPDL actor.
|
||||
*/
|
||||
void Destroy();
|
||||
|
||||
/**
|
||||
* Called when a RecordedTextureData is write locked.
|
||||
*/
|
||||
void OnTextureWriteLock();
|
||||
|
||||
/**
|
||||
* Called when a RecordedTextureData is forwarded to the compositor.
|
||||
*/
|
||||
void OnTextureForwarded();
|
||||
|
||||
/**
|
||||
* @returns true if we should be caching data surfaces in the GPU process.
|
||||
*/
|
||||
bool ShouldCacheDataSurface() const {
|
||||
return mTransactionsSinceGetDataSurface < kCacheDataSurfaceThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that we have sent a begin transaction event, since the last
|
||||
* end transaction.
|
||||
*/
|
||||
void EnsureBeginTransaction();
|
||||
|
||||
/**
|
||||
* Send an end transaction event to indicate the end of events for this frame.
|
||||
*/
|
||||
void EndTransaction();
|
||||
|
||||
/**
|
||||
* Create a DrawTargetRecording for a canvas texture.
|
||||
* @param aSize size for the DrawTarget
|
||||
* @param aFormat SurfaceFormat for the DrawTarget
|
||||
* @returns newly created DrawTargetRecording
|
||||
*/
|
||||
already_AddRefed<gfx::DrawTarget> CreateDrawTarget(
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
|
||||
|
||||
/**
|
||||
* Record an event for processing by the CanvasParent's CanvasTranslator.
|
||||
* @param aEvent the event to record
|
||||
*/
|
||||
void RecordEvent(const gfx::RecordedEvent& aEvent);
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetDataSurface(
|
||||
const gfx::SourceSurface* aSurface);
|
||||
|
||||
protected:
|
||||
void ActorDestroy(ActorDestroyReason aWhy) final;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CanvasChild);
|
||||
|
||||
~CanvasChild() final;
|
||||
|
||||
static const uint32_t kCacheDataSurfaceThreshold = 10;
|
||||
|
||||
RefPtr<CanvasDrawEventRecorder> mRecorder;
|
||||
TextureType mTextureType = TextureType::Unknown;
|
||||
uint32_t mLastWriteLockCheckpoint = 0;
|
||||
uint32_t mTransactionsSinceGetDataSurface = kCacheDataSurfaceThreshold;
|
||||
bool mCanSend = false;
|
||||
bool mIsInTransaction = false;
|
||||
bool mHasOutstandingWriteLock = false;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_CanvasChild_h
|
125
gfx/layers/ipc/CanvasParent.cpp
Normal file
125
gfx/layers/ipc/CanvasParent.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "CanvasParent.h"
|
||||
|
||||
#include "base/thread.h"
|
||||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include "mozilla/gfx/DeviceManagerDx.h"
|
||||
# include "mozilla/layers/DeviceAttachmentsD3D11.h"
|
||||
#endif
|
||||
|
||||
bool NS_IsInCanvasThread() {
|
||||
return mozilla::layers::CanvasParent::IsInCanvasThread();
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static base::Thread* sCanvasThread = nullptr;
|
||||
|
||||
static MessageLoop* CanvasPlaybackLoop() {
|
||||
if (!sCanvasThread) {
|
||||
MOZ_ASSERT(NS_IsInCompositorThread());
|
||||
base::Thread* canvasThread = new base::Thread("Canvas");
|
||||
if (canvasThread->Start()) {
|
||||
sCanvasThread = canvasThread;
|
||||
}
|
||||
}
|
||||
|
||||
return sCanvasThread ? sCanvasThread->message_loop() : MessageLoop::current();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<CanvasParent> CanvasParent::Create(
|
||||
ipc::Endpoint<PCanvasParent>&& aEndpoint) {
|
||||
MOZ_ASSERT(NS_IsInCompositorThread());
|
||||
|
||||
RefPtr<CanvasParent> canvasParent = new CanvasParent();
|
||||
if (CanvasPlaybackLoop()->IsAcceptingTasks()) {
|
||||
RefPtr<Runnable> runnable = NewRunnableMethod<Endpoint<PCanvasParent>&&>(
|
||||
"CanvasParent::Bind", canvasParent, &CanvasParent::Bind,
|
||||
std::move(aEndpoint));
|
||||
CanvasPlaybackLoop()->PostTask(runnable.forget());
|
||||
}
|
||||
return do_AddRef(canvasParent);
|
||||
}
|
||||
|
||||
/* static */ bool CanvasParent::IsInCanvasThread() {
|
||||
return sCanvasThread &&
|
||||
sCanvasThread->thread_id() == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
/* static */ void CanvasParent::Shutdown() {
|
||||
if (sCanvasThread) {
|
||||
delete sCanvasThread;
|
||||
sCanvasThread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CanvasParent::CanvasParent() {}
|
||||
|
||||
CanvasParent::~CanvasParent() {}
|
||||
|
||||
void CanvasParent::Bind(Endpoint<PCanvasParent>&& aEndpoint) {
|
||||
if (!aEndpoint.Bind(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSelfRef = this;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CanvasParent::RecvCreateTranslator(
|
||||
const TextureType& aTextureType,
|
||||
const ipc::SharedMemoryBasic::Handle& aReadHandle,
|
||||
const CrossProcessSemaphoreHandle& aReaderSem,
|
||||
const CrossProcessSemaphoreHandle& aWriterSem) {
|
||||
mTranslator = CanvasTranslator::Create(aTextureType, aReadHandle, aReaderSem,
|
||||
aWriterSem);
|
||||
return RecvResumeTranslation();
|
||||
}
|
||||
|
||||
ipc::IPCResult CanvasParent::RecvResumeTranslation() {
|
||||
MOZ_ASSERT(mTranslator);
|
||||
|
||||
if (!mTranslator->IsValid()) {
|
||||
return IPC_FAIL(this, "Canvas Translation failed.");
|
||||
}
|
||||
|
||||
PostStartTranslationTask();
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void CanvasParent::PostStartTranslationTask() {
|
||||
if (MessageLoop::current()->IsAcceptingTasks()) {
|
||||
RefPtr<Runnable> runnable =
|
||||
NewRunnableMethod("CanvasParent::StartTranslation", this,
|
||||
&CanvasParent::StartTranslation);
|
||||
MessageLoop::current()->PostTask(runnable.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasParent::StartTranslation() {
|
||||
if (!mTranslator->TranslateRecording()) {
|
||||
PostStartTranslationTask();
|
||||
}
|
||||
}
|
||||
|
||||
UniquePtr<SurfaceDescriptor>
|
||||
CanvasParent::LookupSurfaceDescriptorForClientDrawTarget(
|
||||
const uintptr_t aDrawTarget) {
|
||||
return mTranslator->WaitForSurfaceDescriptor(
|
||||
reinterpret_cast<void*>(aDrawTarget));
|
||||
}
|
||||
|
||||
void CanvasParent::DeallocPCanvasParent() { mSelfRef = nullptr; }
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
97
gfx/layers/ipc/CanvasParent.h
Normal file
97
gfx/layers/ipc/CanvasParent.h
Normal file
@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_layers_CanvasParent_h
|
||||
#define mozilla_layers_CanvasParent_h
|
||||
|
||||
#include "mozilla/ipc/CrossProcessSemaphore.h"
|
||||
#include "mozilla/layers/CanvasTranslator.h"
|
||||
#include "mozilla/layers/PCanvasParent.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class TextureData;
|
||||
|
||||
class CanvasParent final : public PCanvasParent {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CanvasParent)
|
||||
|
||||
friend class PProtocolParent;
|
||||
|
||||
/**
|
||||
* Create a CanvasParent and bind it to the given endpoint on the
|
||||
* CanvasPlaybackLoop.
|
||||
*
|
||||
* @params aEndpoint the endpoint to bind to
|
||||
* @returns the new CanvasParent
|
||||
*/
|
||||
static already_AddRefed<CanvasParent> Create(
|
||||
Endpoint<PCanvasParent>&& aEndpoint);
|
||||
|
||||
static bool IsInCanvasThread();
|
||||
|
||||
/**
|
||||
* Shutdown the canvas thread.
|
||||
*/
|
||||
static void Shutdown();
|
||||
|
||||
/**
|
||||
* Create a canvas translator for a particular TextureType, which translates
|
||||
* events from a CanvasEventRingBuffer.
|
||||
*
|
||||
* @param aTextureType the TextureType the translator will create
|
||||
* @param aReadHandle handle to the shared memory for the
|
||||
* CanvasEventRingBuffer
|
||||
* @param aReaderSem reading blocked semaphore for the CanvasEventRingBuffer
|
||||
* @param aWriterSem writing blocked semaphore for the CanvasEventRingBuffer
|
||||
*/
|
||||
ipc::IPCResult RecvCreateTranslator(
|
||||
const TextureType& aTextureType,
|
||||
const ipc::SharedMemoryBasic::Handle& aReadHandle,
|
||||
const CrossProcessSemaphoreHandle& aReaderSem,
|
||||
const CrossProcessSemaphoreHandle& aWriterSem);
|
||||
|
||||
/**
|
||||
* Used to tell the CanvasTranslator to start translating again after it has
|
||||
* stopped due to a timeout waiting for events.
|
||||
*/
|
||||
ipc::IPCResult RecvResumeTranslation();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason why) final {}
|
||||
|
||||
void DeallocPCanvasParent();
|
||||
|
||||
/**
|
||||
* Used by the compositor thread to get the SurfaceDescriptor associated with
|
||||
* the DrawTarget from another process.
|
||||
*
|
||||
* @param aDrawTarget the key to find the TextureData
|
||||
* @returns the SurfaceDescriptor associated with the key
|
||||
*/
|
||||
UniquePtr<SurfaceDescriptor> LookupSurfaceDescriptorForClientDrawTarget(
|
||||
const uintptr_t aDrawTarget);
|
||||
|
||||
private:
|
||||
CanvasParent();
|
||||
~CanvasParent() final;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CanvasParent);
|
||||
|
||||
void Bind(Endpoint<PCanvasParent>&& aEndpoint);
|
||||
|
||||
void PostStartTranslationTask();
|
||||
|
||||
void StartTranslation();
|
||||
|
||||
RefPtr<CanvasParent> mSelfRef;
|
||||
UniquePtr<CanvasTranslator> mTranslator;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_CanvasParent_h
|
@ -18,6 +18,7 @@
|
||||
#include "mozilla/layers/APZChild.h"
|
||||
#include "mozilla/layers/IAPZCTreeManager.h"
|
||||
#include "mozilla/layers/APZCTreeManagerChild.h"
|
||||
#include "mozilla/layers/CanvasChild.h"
|
||||
#include "mozilla/layers/LayerTransactionChild.h"
|
||||
#include "mozilla/layers/PaintThread.h"
|
||||
#include "mozilla/layers/PLayerTransactionChild.h"
|
||||
@ -117,6 +118,10 @@ void CompositorBridgeChild::AfterDestroy() {
|
||||
mActorDestroyed = true;
|
||||
}
|
||||
|
||||
if (mCanvasChild) {
|
||||
mCanvasChild->Destroy();
|
||||
}
|
||||
|
||||
if (sCompositorBridge == this) {
|
||||
sCompositorBridge = nullptr;
|
||||
}
|
||||
@ -245,6 +250,18 @@ void CompositorBridgeChild::InitForContent(uint32_t aNamespace) {
|
||||
|
||||
mCanSend = true;
|
||||
mIdNamespace = aNamespace;
|
||||
|
||||
if (gfx::gfxVars::RemoteCanvasEnabled()) {
|
||||
ipc::Endpoint<PCanvasParent> parentEndpoint;
|
||||
ipc::Endpoint<PCanvasChild> childEndpoint;
|
||||
nsresult rv = PCanvas::CreateEndpoints(OtherPid(), base::GetCurrentProcId(),
|
||||
&parentEndpoint, &childEndpoint);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
Unused << SendInitPCanvasParent(std::move(parentEndpoint));
|
||||
mCanvasChild = new CanvasChild(std::move(childEndpoint));
|
||||
}
|
||||
}
|
||||
|
||||
sCompositorBridge = this;
|
||||
}
|
||||
|
||||
@ -918,6 +935,16 @@ PTextureChild* CompositorBridgeChild::CreateTexture(
|
||||
LayersId{0} /* FIXME? */, aSerial, aExternalImageId);
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasChild> CompositorBridgeChild::GetCanvasChild() {
|
||||
return do_AddRef(mCanvasChild);
|
||||
}
|
||||
|
||||
void CompositorBridgeChild::EndCanvasTransaction() {
|
||||
if (mCanvasChild) {
|
||||
mCanvasChild->EndTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
bool CompositorBridgeChild::AllocUnsafeShmem(
|
||||
size_t aSize, ipc::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aShmem) {
|
||||
|
@ -41,6 +41,7 @@ using mozilla::dom::BrowserChild;
|
||||
|
||||
class IAPZCTreeManager;
|
||||
class APZCTreeManagerChild;
|
||||
class CanvasChild;
|
||||
class ClientLayerManager;
|
||||
class CompositorBridgeParent;
|
||||
class CompositorManagerChild;
|
||||
@ -122,6 +123,10 @@ class CompositorBridgeChild final : public PCompositorBridgeChild,
|
||||
wr::MaybeExternalImageId& aExternalImageId,
|
||||
nsIEventTarget* aTarget) override;
|
||||
|
||||
already_AddRefed<CanvasChild> GetCanvasChild() final;
|
||||
|
||||
void EndCanvasTransaction();
|
||||
|
||||
/**
|
||||
* Request that the parent tell us when graphics are ready on GPU.
|
||||
* When we get that message, we bounce it to the BrowserParent via
|
||||
@ -391,6 +396,8 @@ class CompositorBridgeChild final : public PCompositorBridgeChild,
|
||||
|
||||
uintptr_t mSlowFlushCount;
|
||||
uintptr_t mTotalFlushCount;
|
||||
|
||||
RefPtr<CanvasChild> mCanvasChild;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -2283,6 +2283,11 @@ bool CompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor) {
|
||||
return TextureHost::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CompositorBridgeParent::RecvInitPCanvasParent(
|
||||
Endpoint<PCanvasParent>&& aEndpoint) {
|
||||
MOZ_CRASH("PCanvasParent shouldn't be created via CompositorBridgeParent.");
|
||||
}
|
||||
|
||||
bool CompositorBridgeParent::IsSameProcess() const {
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ class PAPZParent;
|
||||
class ContentCompositorBridgeParent;
|
||||
class CompositorThreadHolder;
|
||||
class InProcessCompositorSession;
|
||||
class TextureData;
|
||||
class WebRenderBridgeParent;
|
||||
|
||||
struct ScopedLayerTreeRegistration {
|
||||
@ -188,6 +189,11 @@ class CompositorBridgeParentBase : public PCompositorBridgeParent,
|
||||
|
||||
virtual bool IsRemote() const { return false; }
|
||||
|
||||
virtual UniquePtr<SurfaceDescriptor>
|
||||
LookupSurfaceDescriptorForClientDrawTarget(const uintptr_t aDrawTarget) {
|
||||
MOZ_CRASH("Should only be called on ContentCompositorBridgeParent.");
|
||||
}
|
||||
|
||||
virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget,
|
||||
const gfx::IntRect* aRect = nullptr) {
|
||||
MOZ_CRASH();
|
||||
@ -265,6 +271,8 @@ class CompositorBridgeParentBase : public PCompositorBridgeParent,
|
||||
const uint32_t& startIndex, nsTArray<float>* intervals) = 0;
|
||||
virtual mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(
|
||||
const uint32_t& sequenceNum, bool* isContentOnlyTDR) = 0;
|
||||
virtual mozilla::ipc::IPCResult RecvInitPCanvasParent(
|
||||
Endpoint<PCanvasParent>&& aEndpoint) = 0;
|
||||
|
||||
bool mCanSend;
|
||||
|
||||
@ -388,6 +396,9 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
|
||||
const wr::MaybeExternalImageId& aExternalImageId) override;
|
||||
bool DeallocPTextureParent(PTextureParent* actor) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvInitPCanvasParent(
|
||||
Endpoint<PCanvasParent>&& aEndpoint) final;
|
||||
|
||||
bool IsSameProcess() const override;
|
||||
|
||||
void NotifyWebRenderContextPurge();
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CanvasParent.h"
|
||||
#include "mozilla/layers/CompositorManagerParent.h"
|
||||
#include "mozilla/layers/ImageBridgeParent.h"
|
||||
#include "mozilla/media/MediaSystemResourceService.h"
|
||||
@ -127,6 +128,7 @@ void CompositorThreadHolder::Shutdown() {
|
||||
gfx::ReleaseVRManagerParentSingleton();
|
||||
MediaSystemResourceService::Shutdown();
|
||||
CompositorManagerParent::Shutdown();
|
||||
CanvasParent::Shutdown();
|
||||
|
||||
sCompositorThreadHolder = nullptr;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
|
||||
#include "mozilla/layers/APZUpdater.h" // for APZUpdater
|
||||
#include "mozilla/layers/AsyncCompositionManager.h"
|
||||
#include "mozilla/layers/CanvasParent.h"
|
||||
#include "mozilla/layers/CompositorOptions.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
@ -614,6 +615,22 @@ bool ContentCompositorBridgeParent::DeallocPTextureParent(
|
||||
return TextureHost::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvInitPCanvasParent(
|
||||
Endpoint<PCanvasParent>&& aEndpoint) {
|
||||
MOZ_RELEASE_ASSERT(!mCanvasParent,
|
||||
"Canvas Parent should only be created once per "
|
||||
"CrossProcessCompositorBridgeParent.");
|
||||
|
||||
mCanvasParent = CanvasParent::Create(std::move(aEndpoint));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
UniquePtr<SurfaceDescriptor>
|
||||
ContentCompositorBridgeParent::LookupSurfaceDescriptorForClientDrawTarget(
|
||||
const uintptr_t aDrawTarget) {
|
||||
return mCanvasParent->LookupSurfaceDescriptorForClientDrawTarget(aDrawTarget);
|
||||
}
|
||||
|
||||
bool ContentCompositorBridgeParent::IsSameProcess() const {
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
@ -9,10 +9,12 @@
|
||||
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CanvasParent;
|
||||
class CompositorOptions;
|
||||
|
||||
/**
|
||||
@ -153,6 +155,9 @@ class ContentCompositorBridgeParent final : public CompositorBridgeParentBase {
|
||||
|
||||
bool DeallocPTextureParent(PTextureParent* actor) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvInitPCanvasParent(
|
||||
Endpoint<PCanvasParent>&& aEndpoint) final;
|
||||
|
||||
bool IsSameProcess() const override;
|
||||
|
||||
PCompositorWidgetParent* AllocPCompositorWidgetParent(
|
||||
@ -188,6 +193,9 @@ class ContentCompositorBridgeParent final : public CompositorBridgeParentBase {
|
||||
|
||||
bool IsRemote() const override { return true; }
|
||||
|
||||
UniquePtr<SurfaceDescriptor> LookupSurfaceDescriptorForClientDrawTarget(
|
||||
const uintptr_t aDrawTarget) final;
|
||||
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
virtual ~ContentCompositorBridgeParent();
|
||||
@ -203,6 +211,8 @@ class ContentCompositorBridgeParent final : public CompositorBridgeParentBase {
|
||||
// transaction is received
|
||||
bool mNotifyAfterRemotePaint;
|
||||
bool mDestroyCalled;
|
||||
|
||||
RefPtr<CanvasParent> mCanvasParent;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -133,6 +133,10 @@ struct SurfaceDescriptorShared
|
||||
Handle handle;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorRecorded {
|
||||
uintptr_t drawTarget;
|
||||
};
|
||||
|
||||
union SurfaceDescriptor {
|
||||
SurfaceDescriptorBuffer;
|
||||
SurfaceDescriptorDIB;
|
||||
@ -145,6 +149,7 @@ union SurfaceDescriptor {
|
||||
SurfaceDescriptorMacIOSurface;
|
||||
SurfaceDescriptorSharedGLTexture;
|
||||
SurfaceDescriptorGPUVideo;
|
||||
SurfaceDescriptorRecorded;
|
||||
null_t;
|
||||
};
|
||||
|
||||
|
37
gfx/layers/ipc/PCanvas.ipdl
Normal file
37
gfx/layers/ipc/PCanvas.ipdl
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et : */
|
||||
/* 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/. */
|
||||
|
||||
using mozilla::CrossProcessSemaphoreHandle from "mozilla/ipc/CrossProcessSemaphore.h";
|
||||
using mozilla::layers::TextureType from "mozilla/layers/LayersTypes.h";
|
||||
using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* PCanvas is the IPDL for recorded Canvas drawing.
|
||||
*/
|
||||
sync protocol PCanvas {
|
||||
parent:
|
||||
/**
|
||||
* Create a CanvasTranslator for a particular TextureType, which translates
|
||||
* events from a CanvasEventRingBuffer. aReadHandle is the shared memory
|
||||
* handle for the ring buffer. aReaderSem and aWriterSem are handles for the
|
||||
* semaphores to handle waiting on either side.
|
||||
*/
|
||||
async CreateTranslator(TextureType aTextureType, Handle aReadHandle,
|
||||
CrossProcessSemaphoreHandle aReaderSem,
|
||||
CrossProcessSemaphoreHandle aWriterSem);
|
||||
|
||||
/**
|
||||
* Used to tell the CanvasTranslator to start translating again after it has
|
||||
* stopped due to a timeout waiting for events.
|
||||
*/
|
||||
async ResumeTranslation();
|
||||
};
|
||||
|
||||
} // layers
|
||||
} // mozilla
|
@ -11,6 +11,7 @@ include PlatformWidgetTypes;
|
||||
include protocol PAPZ;
|
||||
include protocol PAPZCTreeManager;
|
||||
include protocol PBrowser;
|
||||
include protocol PCanvas;
|
||||
include protocol PCompositorManager;
|
||||
include protocol PCompositorWidget;
|
||||
include protocol PLayerTransaction;
|
||||
@ -255,6 +256,8 @@ parent:
|
||||
|
||||
async PTexture(SurfaceDescriptor aSharedData, ReadLockDescriptor aReadLock, LayersBackend aBackend, TextureFlags aTextureFlags, LayersId id, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
|
||||
|
||||
async InitPCanvasParent(Endpoint<PCanvasParent> aEndpoint);
|
||||
|
||||
sync SyncWithCompositor();
|
||||
|
||||
// The pipelineId is the same as the layersId
|
||||
|
@ -19,6 +19,7 @@ namespace ipc {
|
||||
class IShmemAllocator;
|
||||
}
|
||||
namespace layers {
|
||||
class CanvasChild;
|
||||
|
||||
/**
|
||||
* An abstract interface for classes that implement the autogenerated
|
||||
@ -78,6 +79,11 @@ class TextureForwarder : public LayersIPCChannel {
|
||||
LayersBackend aLayersBackend, TextureFlags aFlags, uint64_t aSerial,
|
||||
wr::MaybeExternalImageId& aExternalImageId,
|
||||
nsIEventTarget* aTarget = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* Returns the CanvasChild for this TextureForwarder.
|
||||
*/
|
||||
virtual already_AddRefed<CanvasChild> GetCanvasChild() { return nullptr; };
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -130,7 +130,9 @@ EXPORTS.mozilla.layers += [
|
||||
'basic/TextureHostBasic.h',
|
||||
'BSPTree.h',
|
||||
'BufferTexture.h',
|
||||
'CanvasDrawEventRecorder.h',
|
||||
'CanvasRenderer.h',
|
||||
'CanvasTranslator.h',
|
||||
'client/CanvasClient.h',
|
||||
'client/CompositableClient.h',
|
||||
'client/ContentClient.h',
|
||||
@ -142,6 +144,7 @@ EXPORTS.mozilla.layers += [
|
||||
'client/TextureClientPool.h',
|
||||
'client/TextureClientRecycleAllocator.h',
|
||||
'client/TextureClientSharedSurface.h',
|
||||
'client/TextureRecorded.h',
|
||||
'client/TiledContentClient.h',
|
||||
'composite/AsyncCompositionManager.h',
|
||||
'composite/CanvasLayerComposite.h',
|
||||
@ -176,6 +179,8 @@ EXPORTS.mozilla.layers += [
|
||||
'ipc/APZCTreeManagerParent.h',
|
||||
'ipc/APZInputBridgeChild.h',
|
||||
'ipc/APZInputBridgeParent.h',
|
||||
'ipc/CanvasChild.h',
|
||||
'ipc/CanvasParent.h',
|
||||
'ipc/CompositableForwarder.h',
|
||||
'ipc/CompositableTransactionParent.h',
|
||||
'ipc/CompositorBridgeChild.h',
|
||||
@ -371,7 +376,9 @@ UNIFIED_SOURCES += [
|
||||
'basic/TextureHostBasic.cpp',
|
||||
'BSPTree.cpp',
|
||||
'BufferTexture.cpp',
|
||||
'CanvasDrawEventRecorder.cpp',
|
||||
'CanvasRenderer.cpp',
|
||||
'CanvasTranslator.cpp',
|
||||
'client/CanvasClient.cpp',
|
||||
'client/ClientCanvasLayer.cpp',
|
||||
'client/ClientCanvasRenderer.cpp',
|
||||
@ -391,6 +398,7 @@ UNIFIED_SOURCES += [
|
||||
'client/TextureClientPool.cpp',
|
||||
'client/TextureClientRecycleAllocator.cpp',
|
||||
'client/TextureClientSharedSurface.cpp',
|
||||
'client/TextureRecorded.cpp',
|
||||
'client/TiledContentClient.cpp',
|
||||
'composite/AsyncCompositionManager.cpp',
|
||||
'composite/CanvasLayerComposite.cpp',
|
||||
@ -424,6 +432,8 @@ UNIFIED_SOURCES += [
|
||||
'ipc/APZCTreeManagerParent.cpp',
|
||||
'ipc/APZInputBridgeChild.cpp',
|
||||
'ipc/APZInputBridgeParent.cpp',
|
||||
'ipc/CanvasChild.cpp',
|
||||
'ipc/CanvasParent.cpp',
|
||||
'ipc/CompositableTransactionParent.cpp',
|
||||
'ipc/CompositorBench.cpp',
|
||||
'ipc/CompositorBridgeChild.cpp',
|
||||
@ -540,6 +550,7 @@ IPDL_SOURCES += [
|
||||
'ipc/PAPZ.ipdl',
|
||||
'ipc/PAPZCTreeManager.ipdl',
|
||||
'ipc/PAPZInputBridge.ipdl',
|
||||
'ipc/PCanvas.ipdl',
|
||||
'ipc/PCompositorBridge.ipdl',
|
||||
'ipc/PCompositorManager.ipdl',
|
||||
'ipc/PImageBridge.ipdl',
|
||||
|
@ -245,6 +245,8 @@ bool WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags) {
|
||||
}
|
||||
}
|
||||
|
||||
GetCompositorBridgeChild()->EndCanvasTransaction();
|
||||
|
||||
AutoTArray<RenderRootUpdates, wr::kRenderRootCount> renderRootUpdates;
|
||||
for (auto& stateManager : mStateManagers) {
|
||||
auto renderRoot = stateManager.GetRenderRoot();
|
||||
@ -428,6 +430,8 @@ void WebRenderLayerManager::EndTransactionWithoutLayer(
|
||||
}
|
||||
}
|
||||
|
||||
GetCompositorBridgeChild()->EndCanvasTransaction();
|
||||
|
||||
{
|
||||
AUTO_PROFILER_TRACING("Paint", "ForwardDPTransaction", GRAPHICS);
|
||||
InfallibleTArray<RenderRootDisplayListData> renderRootDLs;
|
||||
|
@ -369,6 +369,8 @@ bool SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr) {
|
||||
*/
|
||||
extern bool NS_IsInCompositorThread();
|
||||
|
||||
extern bool NS_IsInCanvasThread();
|
||||
|
||||
extern bool NS_IsInVRThread();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user