зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 7e1da430d9f9::7c56a10468d7 (bug 1331944) for bustage on Android at gfx/layers/ipc/SharedSurfacesParent.cpp r=backout on a CLOSED TREE
Backed out changeset 7c56a10468d7 (bug 1331944) Backed out changeset b77eb1c48b73 (bug 1331944) Backed out changeset 50b1fcf13fba (bug 1331944) Backed out changeset 56e6ab347bae (bug 1331944) Backed out changeset 5bdfda0b0b3a (bug 1331944) Backed out changeset 40ec55507394 (bug 1331944) Backed out changeset 83cc1f67e9f7 (bug 1331944) Backed out changeset 7e1da430d9f9 (bug 1331944)
This commit is contained in:
Родитель
8e8fe037ac
Коммит
dfaf24241e
|
@ -11,43 +11,6 @@
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
bool
|
||||
SourceSurfaceSharedDataWrapper::Init(const IntSize& aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat,
|
||||
const SharedMemoryBasic::Handle& aHandle,
|
||||
base::ProcessId aCreatorPid)
|
||||
{
|
||||
MOZ_ASSERT(!mBuf);
|
||||
mSize = aSize;
|
||||
mStride = aStride;
|
||||
mFormat = aFormat;
|
||||
mCreatorPid = aCreatorPid;
|
||||
|
||||
size_t len = GetAlignedDataLength();
|
||||
mBuf = new SharedMemoryBasic();
|
||||
if (NS_WARN_IF(!mBuf->SetHandle(aHandle, ipc::SharedMemory::RightsReadOnly)) ||
|
||||
NS_WARN_IF(!mBuf->Map(len))) {
|
||||
mBuf = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
mBuf->CloseHandle();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSharedDataWrapper::Init(SourceSurfaceSharedData* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(!mBuf);
|
||||
MOZ_ASSERT(aSurface);
|
||||
mSize = aSurface->mSize;
|
||||
mStride = aSurface->mStride;
|
||||
mFormat = aSurface->mFormat;
|
||||
mCreatorPid = base::GetCurrentProcId();
|
||||
mBuf = aSurface->mBuf;
|
||||
}
|
||||
|
||||
bool
|
||||
SourceSurfaceSharedData::Init(const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
|
@ -104,7 +67,6 @@ SourceSurfaceSharedData::ShareToProcess(base::ProcessId aPid,
|
|||
SharedMemoryBasic::Handle& aHandle)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_ASSERT(mHandleCount > 0);
|
||||
|
||||
if (mClosed) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
@ -124,9 +86,6 @@ SourceSurfaceSharedData::CloseHandleInternal()
|
|||
mMutex.AssertCurrentThreadOwns();
|
||||
|
||||
if (mClosed) {
|
||||
MOZ_ASSERT(mHandleCount == 0);
|
||||
MOZ_ASSERT(mFinalized);
|
||||
MOZ_ASSERT(mShared);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -140,7 +99,6 @@ bool
|
|||
SourceSurfaceSharedData::ReallocHandle()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_ASSERT(mHandleCount > 0);
|
||||
MOZ_ASSERT(mClosed);
|
||||
MOZ_ASSERT(mFinalized);
|
||||
|
||||
|
|
|
@ -13,89 +13,6 @@
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class SourceSurfaceSharedData;
|
||||
|
||||
class SourceSurfaceSharedDataWrapper final : public DataSourceSurface
|
||||
{
|
||||
typedef mozilla::ipc::SharedMemoryBasic SharedMemoryBasic;
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceSharedDataWrapper, override)
|
||||
|
||||
SourceSurfaceSharedDataWrapper()
|
||||
: mStride(0)
|
||||
, mFormat(SurfaceFormat::UNKNOWN)
|
||||
{ }
|
||||
|
||||
bool Init(const IntSize& aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat,
|
||||
const SharedMemoryBasic::Handle& aHandle,
|
||||
base::ProcessId aCreatorPid);
|
||||
|
||||
void Init(SourceSurfaceSharedData *aSurface);
|
||||
|
||||
base::ProcessId GetCreatorPid() const
|
||||
{
|
||||
return mCreatorPid;
|
||||
}
|
||||
|
||||
int32_t Stride() override { return mStride; }
|
||||
|
||||
SurfaceType GetType() const override { return SurfaceType::DATA; }
|
||||
IntSize GetSize() const override { return mSize; }
|
||||
SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
uint8_t* GetData() override
|
||||
{
|
||||
return static_cast<uint8_t*>(mBuf->memory());
|
||||
}
|
||||
|
||||
bool OnHeap() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map(MapType, MappedSurface *aMappedSurface) override
|
||||
{
|
||||
aMappedSurface->mData = GetData();
|
||||
aMappedSurface->mStride = mStride;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unmap() override
|
||||
{ }
|
||||
|
||||
bool AddConsumer()
|
||||
{
|
||||
return ++mConsumers == 1;
|
||||
}
|
||||
|
||||
bool RemoveConsumer()
|
||||
{
|
||||
MOZ_ASSERT(mConsumers > 0);
|
||||
return --mConsumers == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t GetDataLength() const
|
||||
{
|
||||
return static_cast<size_t>(mStride) * mSize.height;
|
||||
}
|
||||
|
||||
size_t GetAlignedDataLength() const
|
||||
{
|
||||
return mozilla::ipc::SharedMemory::PageAlignedSize(GetDataLength());
|
||||
}
|
||||
|
||||
int32_t mStride;
|
||||
uint32_t mConsumers;
|
||||
IntSize mSize;
|
||||
RefPtr<SharedMemoryBasic> mBuf;
|
||||
SurfaceFormat mFormat;
|
||||
base::ProcessId mCreatorPid;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used to wrap shared (as in process) data buffers used by a
|
||||
* source surface.
|
||||
|
@ -111,7 +28,6 @@ public:
|
|||
: mMutex("SourceSurfaceSharedData")
|
||||
, mStride(0)
|
||||
, mMapCount(0)
|
||||
, mHandleCount(0)
|
||||
, mFormat(SurfaceFormat::UNKNOWN)
|
||||
, mClosed(false)
|
||||
, mFinalized(false)
|
||||
|
@ -119,7 +35,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
bool Init(const IntSize& aSize,
|
||||
bool Init(const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat);
|
||||
|
||||
|
@ -217,65 +133,17 @@ public:
|
|||
bool ReallocHandle();
|
||||
|
||||
/**
|
||||
* Signals we have finished writing to the buffer and it may be marked as
|
||||
* Indicates we have finished writing to the buffer and it may be marked as
|
||||
* read only. May release the handle if possible (see CloseHandleInternal).
|
||||
*/
|
||||
void Finalize();
|
||||
|
||||
/**
|
||||
* Indicates whether or not the buffer can change. If this returns true, it is
|
||||
* guaranteed to continue to do so for the remainder of the surface's life.
|
||||
*/
|
||||
bool IsFinalized() const
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mFinalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* While a HandleLock exists for the given surface, the shared memory handle
|
||||
* cannot be released.
|
||||
*/
|
||||
class MOZ_STACK_CLASS HandleLock final {
|
||||
public:
|
||||
explicit HandleLock(SourceSurfaceSharedData* aSurface)
|
||||
: mSurface(aSurface)
|
||||
{
|
||||
mSurface->LockHandle();
|
||||
}
|
||||
|
||||
~HandleLock()
|
||||
{
|
||||
mSurface->UnlockHandle();
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<SourceSurfaceSharedData> mSurface;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class SourceSurfaceSharedDataWrapper;
|
||||
|
||||
~SourceSurfaceSharedData() override
|
||||
{
|
||||
MOZ_ASSERT(mMapCount == 0);
|
||||
}
|
||||
|
||||
void LockHandle()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
++mHandleCount;
|
||||
}
|
||||
|
||||
void UnlockHandle()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_ASSERT(mHandleCount > 0);
|
||||
--mHandleCount;
|
||||
mShared = true;
|
||||
CloseHandleInternal();
|
||||
}
|
||||
|
||||
uint8_t* GetDataInternal() const;
|
||||
|
||||
size_t GetDataLength() const
|
||||
|
@ -297,7 +165,6 @@ private:
|
|||
mutable Mutex mMutex;
|
||||
int32_t mStride;
|
||||
int32_t mMapCount;
|
||||
int32_t mHandleCount;
|
||||
IntSize mSize;
|
||||
RefPtr<SharedMemoryBasic> mBuf;
|
||||
RefPtr<SharedMemoryBasic> mOldBuf;
|
||||
|
|
|
@ -48,21 +48,8 @@ public:
|
|||
CreateSameProcessWidgetCompositorBridge(LayerManager* aLayerManager,
|
||||
uint32_t aNamespace);
|
||||
|
||||
static CompositorManagerChild* GetInstance()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
bool CanSend() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mCanSend;
|
||||
}
|
||||
|
||||
uint32_t GetNextResourceId()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return ++mResourceId;
|
||||
}
|
||||
|
||||
|
@ -71,19 +58,6 @@ public:
|
|||
return mNamespace;
|
||||
}
|
||||
|
||||
bool OwnsExternalImageId(const wr::ExternalImageId& aId) const
|
||||
{
|
||||
return mNamespace == static_cast<uint32_t>(wr::AsUint64(aId) >> 32);
|
||||
}
|
||||
|
||||
wr::ExternalImageId GetNextExternalImageId()
|
||||
{
|
||||
uint64_t id = GetNextResourceId();
|
||||
MOZ_RELEASE_ASSERT(id != 0);
|
||||
id |= (static_cast<uint64_t>(mNamespace) << 32);
|
||||
return wr::ToExternalImageId(id);
|
||||
}
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
void HandleFatalError(const char* aName, const char* aMsg) const override;
|
||||
|
@ -111,6 +85,12 @@ private:
|
|||
{
|
||||
}
|
||||
|
||||
bool CanSend() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mCanSend;
|
||||
}
|
||||
|
||||
void DeallocPCompositorManagerChild() override;
|
||||
|
||||
already_AddRefed<nsIEventTarget>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/SharedSurfacesParent.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "VsyncSource.h"
|
||||
|
||||
|
@ -151,8 +150,6 @@ CompositorManagerParent::BindComplete()
|
|||
void
|
||||
CompositorManagerParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
SharedSurfacesParent::DestroyProcess(OtherPid());
|
||||
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (sInstance == this) {
|
||||
sInstance = nullptr;
|
||||
|
@ -276,20 +273,5 @@ CompositorManagerParent::DeallocPCompositorBridgeParent(PCompositorBridgeParent*
|
|||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
CompositorManagerParent::RecvAddSharedSurface(const wr::ExternalImageId& aId,
|
||||
const SurfaceDescriptorShared& aDesc)
|
||||
{
|
||||
SharedSurfacesParent::Add(aId, aDesc, OtherPid());
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
CompositorManagerParent::RecvRemoveSharedSurface(const wr::ExternalImageId& aId)
|
||||
{
|
||||
SharedSurfacesParent::Remove(aId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -39,10 +39,6 @@ public:
|
|||
bool aUseExternalSurfaceSize,
|
||||
const gfx::IntSize& aSurfaceSize);
|
||||
|
||||
mozilla::ipc::IPCResult RecvAddSharedSurface(const wr::ExternalImageId& aId,
|
||||
const SurfaceDescriptorShared& aDesc) override;
|
||||
mozilla::ipc::IPCResult RecvRemoveSharedSurface(const wr::ExternalImageId& aId) override;
|
||||
|
||||
void BindComplete();
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/ImageBridgeParent.h"
|
||||
#include "mozilla/layers/SharedSurfacesParent.h"
|
||||
#include "mozilla/media/MediaSystemResourceService.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h" // for CrashReporter
|
||||
|
@ -99,7 +98,6 @@ CompositorThreadHolder::DestroyCompositorThread(base::Thread* aCompositorThread)
|
|||
MOZ_ASSERT(!sCompositorThreadHolder, "We shouldn't be destroying the compositor thread yet.");
|
||||
|
||||
CompositorBridgeParent::Shutdown();
|
||||
SharedSurfacesParent::Shutdown();
|
||||
delete aCompositorThread;
|
||||
sFinishedCompositorShutDown = true;
|
||||
}
|
||||
|
@ -134,7 +132,6 @@ CompositorThreadHolder::CreateCompositorThread()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
SharedSurfacesParent::Initialize();
|
||||
CompositorBridgeParent::Setup();
|
||||
ImageBridgeParent::Setup();
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
|
|||
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h";
|
||||
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
|
||||
using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
|
||||
using gfxImageFormat from "gfxTypes.h";
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -128,14 +127,6 @@ struct SurfaceDescriptorBuffer {
|
|||
MemoryOrShmem data;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorShared
|
||||
{
|
||||
IntSize size;
|
||||
int32_t stride;
|
||||
SurfaceFormat format;
|
||||
Handle handle;
|
||||
};
|
||||
|
||||
union SurfaceDescriptor {
|
||||
SurfaceDescriptorBuffer;
|
||||
SurfaceDescriptorDIB;
|
||||
|
@ -148,7 +139,6 @@ union SurfaceDescriptor {
|
|||
SurfaceDescriptorMacIOSurface;
|
||||
SurfaceDescriptorSharedGLTexture;
|
||||
SurfaceDescriptorGPUVideo;
|
||||
SurfaceDescriptorShared;
|
||||
null_t;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,17 +6,12 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PCompositorBridge;
|
||||
include LayersSurfaces;
|
||||
include "mozilla/GfxMessageUtils.h";
|
||||
include "mozilla/layers/WebRenderMessageUtils.h";
|
||||
|
||||
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
using mozilla::TimeDuration from "mozilla/TimeStamp.h";
|
||||
using mozilla::CSSToLayoutDeviceScale from "Units.h";
|
||||
using mozilla::gfx::IntSize from "mozilla/gfx/2D.h";
|
||||
using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
|
||||
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
|
||||
using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -72,9 +67,6 @@ parent:
|
|||
* See gfx/layers/ipc/PCompositorBridge.ipdl for more details.
|
||||
*/
|
||||
async PCompositorBridge(CompositorBridgeOptions options);
|
||||
|
||||
async AddSharedSurface(ExternalImageId aId, SurfaceDescriptorShared aDesc);
|
||||
async RemoveSharedSurface(ExternalImageId aId);
|
||||
};
|
||||
|
||||
} // layers
|
||||
|
|
|
@ -1,214 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "SharedSurfacesChild.h"
|
||||
#include "SharedSurfacesParent.h"
|
||||
#include "CompositorManagerChild.h"
|
||||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
#include "mozilla/SystemGroup.h" // for SystemGroup
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
class SharedSurfacesChild::SharedUserData final
|
||||
{
|
||||
public:
|
||||
explicit SharedUserData(const wr::ExternalImageId& aId)
|
||||
: mId(aId)
|
||||
, mShared(false)
|
||||
{ }
|
||||
|
||||
~SharedUserData()
|
||||
{
|
||||
if (mShared) {
|
||||
mShared = false;
|
||||
if (NS_IsMainThread()) {
|
||||
SharedSurfacesChild::Unshare(mId);
|
||||
} else {
|
||||
wr::ExternalImageId id = mId;
|
||||
SystemGroup::Dispatch(TaskCategory::Other,
|
||||
NS_NewRunnableFunction("DestroySharedUserData",
|
||||
[id]() -> void {
|
||||
SharedSurfacesChild::Unshare(id);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wr::ExternalImageId& Id() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
void SetId(const wr::ExternalImageId& aId)
|
||||
{
|
||||
mId = aId;
|
||||
mShared = false;
|
||||
}
|
||||
|
||||
bool IsShared() const
|
||||
{
|
||||
return mShared;
|
||||
}
|
||||
|
||||
void MarkShared()
|
||||
{
|
||||
MOZ_ASSERT(!mShared);
|
||||
mShared = true;
|
||||
}
|
||||
|
||||
private:
|
||||
wr::ExternalImageId mId;
|
||||
bool mShared : 1;
|
||||
};
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesChild::DestroySharedUserData(void* aClosure)
|
||||
{
|
||||
MOZ_ASSERT(aClosure);
|
||||
auto data = static_cast<SharedUserData*>(aClosure);
|
||||
delete data;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
SharedSurfacesChild::Share(SourceSurfaceSharedData* aSurface,
|
||||
wr::ExternalImageId& aId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
CompositorManagerChild* manager = CompositorManagerChild::GetInstance();
|
||||
if (NS_WARN_IF(!manager || !manager->CanSend())) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
static UserDataKey sSharedKey;
|
||||
SharedUserData* data =
|
||||
static_cast<SharedUserData*>(aSurface->GetUserData(&sSharedKey));
|
||||
if (!data) {
|
||||
data = new SharedUserData(manager->GetNextExternalImageId());
|
||||
aSurface->AddUserData(&sSharedKey, data, DestroySharedUserData);
|
||||
} else if (!manager->OwnsExternalImageId(data->Id())) {
|
||||
// If the id isn't owned by us, that means the bridge was reinitialized, due
|
||||
// to the GPU process crashing. All previous mappings have been released.
|
||||
MOZ_ASSERT(manager->OtherPid() != base::GetCurrentProcId());
|
||||
data->SetId(manager->GetNextExternalImageId());
|
||||
} else if (data->IsShared()) {
|
||||
// It has already been shared with the GPU process, reuse the id.
|
||||
aId = data->Id();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Ensure that the handle doesn't get released until after we have finished
|
||||
// sending the buffer to the GPU process and/or reallocating it.
|
||||
// FinishedSharing is not a sufficient condition because another thread may
|
||||
// decide we are done while we are in the processing of sharing our newly
|
||||
// reallocated handle. Once it goes out of scope, it may release the handle.
|
||||
SourceSurfaceSharedData::HandleLock lock(aSurface);
|
||||
|
||||
// If we live in the same process, then it is a simple matter of directly
|
||||
// asking the parent instance to store a pointer to the same data, no need
|
||||
// to map the data into our memory space twice.
|
||||
auto pid = manager->OtherPid();
|
||||
if (pid == base::GetCurrentProcId()) {
|
||||
SharedSurfacesParent::AddSameProcess(data->Id(), aSurface);
|
||||
data->MarkShared();
|
||||
aId = data->Id();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Attempt to share a handle with the GPU process. The handle may or may not
|
||||
// be available -- it will only be available if it is either not yet finalized
|
||||
// and/or if it has been finalized but never used for drawing in process.
|
||||
ipc::SharedMemoryBasic::Handle handle = ipc::SharedMemoryBasic::NULLHandle();
|
||||
nsresult rv = aSurface->ShareToProcess(pid, handle);
|
||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
// It is at least as expensive to copy the image to the GPU process if we
|
||||
// have already closed the handle necessary to share, but if we reallocate
|
||||
// the shared buffer to get a new handle, we can save some memory.
|
||||
if (NS_WARN_IF(!aSurface->ReallocHandle())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Reattempt the sharing of the handle to the GPU process.
|
||||
rv = aSurface->ShareToProcess(pid, handle);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_ASSERT(rv != NS_ERROR_NOT_AVAILABLE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SurfaceFormat format = aSurface->GetFormat();
|
||||
MOZ_RELEASE_ASSERT(format == SurfaceFormat::B8G8R8X8 ||
|
||||
format == SurfaceFormat::B8G8R8A8, "bad format");
|
||||
|
||||
data->MarkShared();
|
||||
aId = data->Id();
|
||||
manager->SendAddSharedSurface(aId,
|
||||
SurfaceDescriptorShared(aSurface->GetSize(),
|
||||
aSurface->Stride(),
|
||||
format, handle));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
SharedSurfacesChild::Share(ImageContainer* aContainer,
|
||||
wr::ExternalImageId& aId,
|
||||
uint32_t& aGeneration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aContainer);
|
||||
|
||||
if (aContainer->IsAsync()) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
AutoTArray<ImageContainer::OwningImage,4> images;
|
||||
aContainer->GetCurrentImages(&images, &aGeneration);
|
||||
if (images.IsEmpty()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
RefPtr<gfx::SourceSurface> surface = images[0].mImage->GetAsSourceSurface();
|
||||
if (!surface) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (surface->GetType() != SurfaceType::DATA_SHARED) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
auto sharedSurface = static_cast<SourceSurfaceSharedData*>(surface.get());
|
||||
return Share(sharedSurface, aId);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesChild::Unshare(const wr::ExternalImageId& aId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
CompositorManagerChild* manager = CompositorManagerChild::GetInstance();
|
||||
if (MOZ_UNLIKELY(!manager || !manager->CanSend())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (manager->OtherPid() == base::GetCurrentProcId()) {
|
||||
// We are in the combined UI/GPU process. Call directly to it to remove its
|
||||
// wrapper surface to free the underlying buffer.
|
||||
MOZ_ASSERT(manager->OwnsExternalImageId(aId));
|
||||
SharedSurfacesParent::RemoveSameProcess(aId);
|
||||
} else if (manager->OwnsExternalImageId(aId)) {
|
||||
// Only attempt to release current mappings in the GPU process. It is
|
||||
// possible we had a surface that was previously shared, the GPU process
|
||||
// crashed / was restarted, and then we freed the surface. In that case
|
||||
// we know the mapping has already been freed.
|
||||
manager->SendRemoveSharedSurface(aId);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_SHAREDSURFACESCHILD_H
|
||||
#define MOZILLA_GFX_SHAREDSURFACESCHILD_H
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint32_t, uint64_t
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/RefPtr.h" // for already_AddRefed
|
||||
#include "mozilla/StaticPtr.h" // for StaticRefPtr
|
||||
#include "mozilla/webrender/WebRenderTypes.h" // for wr::ExternalImageId
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class SourceSurfaceSharedData;
|
||||
} // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
|
||||
class CompositorManagerChild;
|
||||
|
||||
class SharedSurfacesChild final
|
||||
{
|
||||
public:
|
||||
static nsresult Share(gfx::SourceSurfaceSharedData* aSurface, wr::ExternalImageId& aId);
|
||||
static nsresult Share(ImageContainer* aContainer, wr::ExternalImageId& aId, uint32_t& aGeneration);
|
||||
|
||||
private:
|
||||
SharedSurfacesChild() = delete;
|
||||
~SharedSurfacesChild() = delete;
|
||||
|
||||
class SharedUserData;
|
||||
|
||||
static void Unshare(const wr::ExternalImageId& aId);
|
||||
static void DestroySharedUserData(void* aClosure);
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,193 +0,0 @@
|
|||
/* vim: set ts=2 sw=2 et tw=80: */
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "SharedSurfacesParent.h"
|
||||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/webrender/RenderSharedSurfaceTextureHost.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
StaticAutoPtr<SharedSurfacesParent> SharedSurfacesParent::sInstance;
|
||||
|
||||
SharedSurfacesParent::SharedSurfacesParent()
|
||||
{
|
||||
}
|
||||
|
||||
SharedSurfacesParent::~SharedSurfacesParent()
|
||||
{
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::Initialize()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!sInstance) {
|
||||
sInstance = new SharedSurfacesParent();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sInstance = nullptr;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<DataSourceSurface>
|
||||
SharedSurfacesParent::Acquire(const wr::ExternalImageId& aId)
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
if (!sInstance) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SourceSurfaceSharedDataWrapper> surface;
|
||||
sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface));
|
||||
|
||||
if (surface) {
|
||||
DebugOnly<bool> rv = surface->AddConsumer();
|
||||
MOZ_ASSERT(!rv);
|
||||
}
|
||||
|
||||
return surface.forget();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
SharedSurfacesParent::Release(const wr::ExternalImageId& aId)
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
if (!sInstance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t id = wr::AsUint64(aId);
|
||||
RefPtr<SourceSurfaceSharedDataWrapper> surface;
|
||||
sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface));
|
||||
if (!surface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (surface->RemoveConsumer()) {
|
||||
sInstance->mSurfaces.Remove(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::AddSameProcess(const wr::ExternalImageId& aId,
|
||||
SourceSurfaceSharedData* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// If the child bridge detects it is in the combined UI/GPU process, then it
|
||||
// will insert a wrapper surface holding the shared memory buffer directly.
|
||||
// This is good because we avoid mapping the same shared memory twice, but
|
||||
// still allow the original surface to be freed and remove the wrapper from
|
||||
// the table when it is no longer needed.
|
||||
RefPtr<SourceSurfaceSharedDataWrapper> surface =
|
||||
new SourceSurfaceSharedDataWrapper();
|
||||
surface->Init(aSurface);
|
||||
|
||||
uint64_t id = wr::AsUint64(aId);
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"layers::SharedSurfacesParent::AddSameProcess",
|
||||
[surface, id]() -> void {
|
||||
if (!sInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!sInstance->mSurfaces.Contains(id));
|
||||
|
||||
RefPtr<wr::RenderSharedSurfaceTextureHost> texture =
|
||||
new wr::RenderSharedSurfaceTextureHost(surface);
|
||||
wr::RenderThread::Get()->RegisterExternalImage(id, texture.forget());
|
||||
|
||||
sInstance->mSurfaces.Put(id, surface);
|
||||
});
|
||||
|
||||
CompositorThreadHolder::Loop()->PostTask(task.forget());
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::RemoveSameProcess(const wr::ExternalImageId& aId)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
const wr::ExternalImageId id(aId);
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"layers::SharedSurfacesParent::RemoveSameProcess",
|
||||
[id]() -> void {
|
||||
Remove(id);
|
||||
});
|
||||
|
||||
CompositorThreadHolder::Loop()->PostTask(task.forget());
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::DestroyProcess(base::ProcessId aPid)
|
||||
{
|
||||
if (!sInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that the destruction of a parent may not be cheap if it still has a
|
||||
// lot of surfaces still bound that require unmapping.
|
||||
for (auto i = sInstance->mSurfaces.Iter(); !i.Done(); i.Next()) {
|
||||
if (i.Data()->GetCreatorPid() == aPid) {
|
||||
wr::RenderThread::Get()->UnregisterExternalImage(i.Key());
|
||||
i.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::Add(const wr::ExternalImageId& aId,
|
||||
const SurfaceDescriptorShared& aDesc,
|
||||
base::ProcessId aPid)
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
MOZ_ASSERT(aPid != base::GetCurrentProcId());
|
||||
if (!sInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that the surface wrapper maps in the given handle as read only.
|
||||
RefPtr<SourceSurfaceSharedDataWrapper> surface =
|
||||
new SourceSurfaceSharedDataWrapper();
|
||||
if (NS_WARN_IF(!surface->Init(aDesc.size(), aDesc.stride(),
|
||||
aDesc.format(), aDesc.handle(),
|
||||
aPid))) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t id = wr::AsUint64(aId);
|
||||
MOZ_ASSERT(!sInstance->mSurfaces.Contains(id));
|
||||
|
||||
RefPtr<wr::RenderSharedSurfaceTextureHost> texture =
|
||||
new wr::RenderSharedSurfaceTextureHost(surface);
|
||||
wr::RenderThread::Get()->RegisterExternalImage(id, texture.forget());
|
||||
|
||||
sInstance->mSurfaces.Put(id, surface.forget());
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::Remove(const wr::ExternalImageId& aId)
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
DebugOnly<bool> rv = Release(aId);
|
||||
MOZ_ASSERT(rv);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
|
@ -1,68 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_SHAREDSURFACESPARENT_H
|
||||
#define MOZILLA_GFX_SHAREDSURFACESPARENT_H
|
||||
|
||||
#include <stdint.h> // for uint32_t
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/StaticPtr.h" // for StaticAutoPtr
|
||||
#include "mozilla/RefPtr.h" // for already_AddRefed
|
||||
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
|
||||
#include "mozilla/gfx/2D.h" // for SurfaceFormat
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/webrender/WebRenderTypes.h" // for wr::ExternalImageId
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class DataSourceSurface;
|
||||
class SourceSurfaceSharedData;
|
||||
class SourceSurfaceSharedDataWrapper;
|
||||
} // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
|
||||
class SharedSurfacesChild;
|
||||
|
||||
class SharedSurfacesParent final
|
||||
{
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
|
||||
static already_AddRefed<gfx::DataSourceSurface>
|
||||
Acquire(const wr::ExternalImageId& aId);
|
||||
|
||||
static bool Release(const wr::ExternalImageId& aId);
|
||||
|
||||
static void Add(const wr::ExternalImageId& aId,
|
||||
const SurfaceDescriptorShared& aDesc,
|
||||
base::ProcessId aPid);
|
||||
|
||||
static void Remove(const wr::ExternalImageId& aId);
|
||||
|
||||
static void DestroyProcess(base::ProcessId aPid);
|
||||
|
||||
~SharedSurfacesParent();
|
||||
|
||||
private:
|
||||
friend class SharedSurfacesChild;
|
||||
|
||||
SharedSurfacesParent();
|
||||
|
||||
static void AddSameProcess(const wr::ExternalImageId& aId,
|
||||
gfx::SourceSurfaceSharedData* aSurface);
|
||||
static void RemoveSameProcess(const wr::ExternalImageId& aId);
|
||||
|
||||
static StaticAutoPtr<SharedSurfacesParent> sInstance;
|
||||
|
||||
nsRefPtrHashtable<nsUint64HashKey, gfx::SourceSurfaceSharedDataWrapper> mSurfaces;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -194,8 +194,6 @@ EXPORTS.mozilla.layers += [
|
|||
'ipc/ShadowLayers.h',
|
||||
'ipc/SharedPlanarYCbCrImage.h',
|
||||
'ipc/SharedRGBImage.h',
|
||||
'ipc/SharedSurfacesChild.h',
|
||||
'ipc/SharedSurfacesParent.h',
|
||||
'ipc/SynchronousTask.h',
|
||||
'ipc/TextureForwarder.h',
|
||||
'ipc/UiCompositorControllerChild.h',
|
||||
|
@ -418,8 +416,6 @@ UNIFIED_SOURCES += [
|
|||
'ipc/ShadowLayers.cpp',
|
||||
'ipc/SharedPlanarYCbCrImage.cpp',
|
||||
'ipc/SharedRGBImage.cpp',
|
||||
'ipc/SharedSurfacesChild.cpp',
|
||||
'ipc/SharedSurfacesParent.cpp',
|
||||
'ipc/UiCompositorControllerChild.cpp',
|
||||
'ipc/UiCompositorControllerParent.cpp',
|
||||
'ipc/VideoBridgeChild.cpp',
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "mozilla/layers/ImageBridgeParent.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/IpcResourceUpdateQueue.h"
|
||||
#include "mozilla/layers/SharedSurfacesParent.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/AsyncImagePipelineManager.h"
|
||||
#include "mozilla/layers/WebRenderImageHost.h"
|
||||
|
@ -359,18 +358,6 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
|
|||
if (keys[0].mNamespace != mIdNamespace) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dSurf = SharedSurfacesParent::Acquire(aExtId);
|
||||
if (dSurf) {
|
||||
if (!gfxEnv::EnableWebRenderRecording()) {
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
aResources.AddExternalImage(aKey, descriptor, aExtId,
|
||||
wr::WrExternalImageBufferType::ExternalBuffer,
|
||||
0);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aExtId)).get());
|
||||
|
||||
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(aExtId));
|
||||
|
@ -391,9 +378,7 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
|
|||
return true;
|
||||
}
|
||||
}
|
||||
dSurf = host->GetAsSurface();
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
|
||||
if (!dSurf) {
|
||||
NS_ERROR("TextureHost does not return DataSourceSurface");
|
||||
return false;
|
||||
|
@ -859,11 +844,6 @@ WebRenderBridgeParent::RecvRemoveExternalImageId(const ExternalImageId& aImageId
|
|||
if (mDestroyed) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (SharedSurfacesParent::Release(aImageId)) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
WebRenderImageHost* wrHost = mExternalImageIds.Get(wr::AsUint64(aImageId)).get();
|
||||
if (!wrHost) {
|
||||
return IPC_OK();
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layers/WebRenderMessages.h"
|
||||
#include "mozilla/layers/IpcResourceUpdateQueue.h"
|
||||
#include "mozilla/layers/SharedSurfacesChild.h"
|
||||
#include "nsDisplayListInvalidation.h"
|
||||
#include "WebRenderCanvasRenderer.h"
|
||||
|
||||
|
@ -50,7 +49,6 @@ WebRenderUserData::WrBridge() const
|
|||
|
||||
WebRenderImageData::WebRenderImageData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
|
||||
: WebRenderUserData(aWRManager, aItem)
|
||||
, mGeneration(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -83,37 +81,19 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
|
|||
wr::IpcResourceUpdateQueue& aResources,
|
||||
bool aForceUpdate)
|
||||
{
|
||||
MOZ_ASSERT(aContainer);
|
||||
CreateImageClientIfNeeded();
|
||||
CreateExternalImageIfNeeded();
|
||||
|
||||
if (mContainer != aContainer) {
|
||||
mContainer = aContainer;
|
||||
}
|
||||
|
||||
wr::ExternalImageId externalId;
|
||||
uint32_t generation;
|
||||
nsresult rv = SharedSurfacesChild::Share(aContainer, externalId, generation);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mExternalImageId.isSome() && mExternalImageId.ref() == externalId) {
|
||||
// The image container has the same surface as before, we can reuse the
|
||||
// key if the generation matches and the caller allows us.
|
||||
if (mKey && mGeneration == generation && !aForceUpdate) {
|
||||
return mKey;
|
||||
}
|
||||
} else {
|
||||
// The image container has a new surface, generate a new image key.
|
||||
mExternalImageId = Some(externalId);
|
||||
}
|
||||
|
||||
mGeneration = generation;
|
||||
} else if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
CreateImageClientIfNeeded();
|
||||
CreateExternalImageIfNeeded();
|
||||
|
||||
if (!mImageClient || !mExternalImageId) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mImageClient->AsImageClientSingle());
|
||||
MOZ_ASSERT(aContainer);
|
||||
|
||||
ImageClientSingle* imageClient = mImageClient->AsImageClientSingle();
|
||||
uint32_t oldCounter = imageClient->GetLastUpdateGenerationCounter();
|
||||
|
@ -132,7 +112,6 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
|
|||
if (!aForceUpdate && oldCounter == imageClient->GetLastUpdateGenerationCounter() && mKey) {
|
||||
return mKey;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete old key, we are generating a new key.
|
||||
// TODO(nical): noooo... we need to reuse image keys.
|
||||
|
|
|
@ -107,7 +107,6 @@ protected:
|
|||
RefPtr<ImageClient> mImageClient;
|
||||
Maybe<wr::PipelineId> mPipelineId;
|
||||
RefPtr<ImageContainer> mContainer;
|
||||
uint32_t mGeneration;
|
||||
};
|
||||
|
||||
class WebRenderFallbackData : public WebRenderImageData
|
||||
|
|
|
@ -43,13 +43,13 @@ RenderBufferTextureHost::~RenderBufferTextureHost()
|
|||
MOZ_COUNT_DTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost);
|
||||
}
|
||||
|
||||
wr::WrExternalImage
|
||||
RenderBufferTextureHost::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
|
||||
bool
|
||||
RenderBufferTextureHost::Lock()
|
||||
{
|
||||
if (!mLocked) {
|
||||
if (!GetBuffer()) {
|
||||
// We hit some problems to get the shmem.
|
||||
return RawDataToWrExternalImage(nullptr, 0);
|
||||
return false;
|
||||
}
|
||||
if (mFormat != gfx::SurfaceFormat::YUV) {
|
||||
mSurface = gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
|
||||
|
@ -57,11 +57,11 @@ RenderBufferTextureHost::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
|
|||
mSize,
|
||||
mFormat);
|
||||
if (NS_WARN_IF(!mSurface)) {
|
||||
return RawDataToWrExternalImage(nullptr, 0);
|
||||
return false;
|
||||
}
|
||||
if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
|
||||
mSurface = nullptr;
|
||||
return RawDataToWrExternalImage(nullptr, 0);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
|
||||
|
@ -80,20 +80,19 @@ RenderBufferTextureHost::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
|
|||
gfx::SurfaceFormat::A8);
|
||||
if (NS_WARN_IF(!mYSurface || !mCbSurface || !mCrSurface)) {
|
||||
mYSurface = mCbSurface = mCrSurface = nullptr;
|
||||
return RawDataToWrExternalImage(nullptr, 0);
|
||||
return false;
|
||||
}
|
||||
if (NS_WARN_IF(!mYSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mYMap) ||
|
||||
!mCbSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCbMap) ||
|
||||
!mCrSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCrMap))) {
|
||||
mYSurface = mCbSurface = mCrSurface = nullptr;
|
||||
return RawDataToWrExternalImage(nullptr, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mLocked = true;
|
||||
}
|
||||
|
||||
RenderBufferData data = GetBufferDataForRender(aChannelIndex);
|
||||
return RawDataToWrExternalImage(data.mData, data.mBufferSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -17,8 +17,13 @@ public:
|
|||
RenderBufferTextureHost(uint8_t* aBuffer,
|
||||
const layers::BufferDescriptor& aDescriptor);
|
||||
|
||||
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
|
||||
void Unlock() override;
|
||||
virtual bool Lock() override;
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual RenderBufferTextureHost* AsBufferTextureHost() override
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
class RenderBufferData
|
||||
{
|
||||
|
|
|
@ -59,6 +59,17 @@ RenderDXGITextureHostOGL::~RenderDXGITextureHostOGL()
|
|||
DeleteTextureHandle();
|
||||
}
|
||||
|
||||
void
|
||||
RenderDXGITextureHostOGL::SetGLContext(gl::GLContext* aContext)
|
||||
{
|
||||
if (mGL.get() != aContext) {
|
||||
// Release the texture handle in the previous gl context.
|
||||
DeleteTextureHandle();
|
||||
mGL = aContext;
|
||||
mGL->MakeCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RenderDXGITextureHostOGL::EnsureLockable()
|
||||
{
|
||||
|
@ -171,34 +182,27 @@ RenderDXGITextureHostOGL::EnsureLockable()
|
|||
return true;
|
||||
}
|
||||
|
||||
wr::WrExternalImage
|
||||
RenderDXGITextureHostOGL::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
|
||||
bool
|
||||
RenderDXGITextureHostOGL::Lock()
|
||||
{
|
||||
if (mGL.get() != aGL) {
|
||||
// Release the texture handle in the previous gl context.
|
||||
DeleteTextureHandle();
|
||||
mGL = aGL;
|
||||
mGL->MakeCurrent();
|
||||
}
|
||||
|
||||
if (!EnsureLockable()) {
|
||||
return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mLocked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mLocked) {
|
||||
if (mKeyedMutex) {
|
||||
HRESULT hr = mKeyedMutex->AcquireSync(0, 100);
|
||||
if (hr != S_OK) {
|
||||
gfxCriticalError() << "RenderDXGITextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
|
||||
return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mLocked = true;
|
||||
}
|
||||
|
||||
gfx::IntSize size = GetSize(aChannelIndex);
|
||||
return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
|
||||
size.width, size.height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -285,6 +289,17 @@ RenderDXGIYCbCrTextureHostOGL::~RenderDXGIYCbCrTextureHostOGL()
|
|||
DeleteTextureHandle();
|
||||
}
|
||||
|
||||
void
|
||||
RenderDXGIYCbCrTextureHostOGL::SetGLContext(gl::GLContext* aContext)
|
||||
{
|
||||
if (mGL.get() != aContext) {
|
||||
// Release the texture handle in the previous gl context.
|
||||
DeleteTextureHandle();
|
||||
mGL = aContext;
|
||||
mGL->MakeCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RenderDXGIYCbCrTextureHostOGL::EnsureLockable()
|
||||
{
|
||||
|
@ -352,36 +367,29 @@ RenderDXGIYCbCrTextureHostOGL::EnsureLockable()
|
|||
return true;
|
||||
}
|
||||
|
||||
wr::WrExternalImage
|
||||
RenderDXGIYCbCrTextureHostOGL::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
|
||||
bool
|
||||
RenderDXGIYCbCrTextureHostOGL::Lock()
|
||||
{
|
||||
if (mGL.get() != aGL) {
|
||||
// Release the texture handle in the previous gl context.
|
||||
DeleteTextureHandle();
|
||||
mGL = aGL;
|
||||
mGL->MakeCurrent();
|
||||
}
|
||||
|
||||
if (!EnsureLockable()) {
|
||||
return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mLocked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mLocked) {
|
||||
if (mKeyedMutexs[0]) {
|
||||
for (const auto& mutex : mKeyedMutexs) {
|
||||
HRESULT hr = mutex->AcquireSync(0, 100);
|
||||
if (hr != S_OK) {
|
||||
gfxCriticalError() << "RenderDXGIYCbCrTextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
|
||||
return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
mLocked = true;
|
||||
}
|
||||
|
||||
gfx::IntSize size = GetSize(aChannelIndex);
|
||||
return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
|
||||
size.width, size.height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -23,8 +23,10 @@ public:
|
|||
gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aSize);
|
||||
|
||||
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
|
||||
void Unlock() override;
|
||||
virtual void SetGLContext(gl::GLContext* aContext) override;
|
||||
|
||||
virtual bool Lock() override;
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const;
|
||||
virtual GLuint GetGLHandle(uint8_t aChannelIndex) const;
|
||||
|
@ -61,7 +63,9 @@ public:
|
|||
explicit RenderDXGIYCbCrTextureHostOGL(WindowsHandle (&aHandles)[3],
|
||||
gfx::IntSize aSize);
|
||||
|
||||
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
|
||||
virtual void SetGLContext(gl::GLContext* aContext) override;
|
||||
|
||||
virtual bool Lock() override;
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const;
|
||||
|
|
|
@ -71,18 +71,11 @@ RenderMacIOSurfaceTextureHostOGL::GetSize(uint8_t aChannelIndex) const
|
|||
mSurface->GetDevicePixelHeight(aChannelIndex));
|
||||
}
|
||||
|
||||
wr::WrExternalImage
|
||||
RenderMacIOSurfaceTextureHostOGL::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
|
||||
bool
|
||||
RenderMacIOSurfaceTextureHostOGL::Lock()
|
||||
{
|
||||
if (mGL.get() != aGL) {
|
||||
// release the texture handle in the previous gl context
|
||||
DeleteTextureHandle();
|
||||
mGL = aGL;
|
||||
mGL->MakeCurrent();
|
||||
}
|
||||
|
||||
if (!mSurface || !mGL || !mGL->MakeCurrent()) {
|
||||
return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mTextureHandles[0]) {
|
||||
|
@ -96,9 +89,7 @@ RenderMacIOSurfaceTextureHostOGL::Lock(uint8_t aChannelIndex, gl::GLContext* aGL
|
|||
}
|
||||
}
|
||||
|
||||
gfx::IntSize size = GetSize(aChannelIndex);
|
||||
return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
|
||||
size.width, size.height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -107,6 +98,17 @@ RenderMacIOSurfaceTextureHostOGL::Unlock()
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
RenderMacIOSurfaceTextureHostOGL::SetGLContext(gl::GLContext* aContext)
|
||||
{
|
||||
if (mGL.get() != aContext) {
|
||||
// release the texture handle in the previous gl context
|
||||
DeleteTextureHandle();
|
||||
mGL = aContext;
|
||||
mGL->MakeCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RenderMacIOSurfaceTextureHostOGL::DeleteTextureHandle()
|
||||
{
|
||||
|
|
|
@ -23,8 +23,10 @@ class RenderMacIOSurfaceTextureHostOGL final : public RenderTextureHostOGL
|
|||
public:
|
||||
explicit RenderMacIOSurfaceTextureHostOGL(MacIOSurface* aSurface);
|
||||
|
||||
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
|
||||
void Unlock() override;
|
||||
virtual bool Lock() override;
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual void SetGLContext(gl::GLContext* aContext) override;
|
||||
|
||||
virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const override;
|
||||
virtual GLuint GetGLHandle(uint8_t aChannelIndex) const override;
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "RenderSharedSurfaceTextureHost.h"
|
||||
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
RenderSharedSurfaceTextureHost::RenderSharedSurfaceTextureHost(gfx::SourceSurfaceSharedDataWrapper* aSurface)
|
||||
: mSurface(aSurface)
|
||||
, mLocked(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(RenderSharedSurfaceTextureHost, RenderTextureHost);
|
||||
MOZ_ASSERT(aSurface);
|
||||
}
|
||||
|
||||
RenderSharedSurfaceTextureHost::~RenderSharedSurfaceTextureHost()
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(RenderSharedSurfaceTextureHost, RenderTextureHost);
|
||||
}
|
||||
|
||||
wr::WrExternalImage
|
||||
RenderSharedSurfaceTextureHost::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
|
||||
{
|
||||
if (!mLocked) {
|
||||
if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE,
|
||||
&mMap))) {
|
||||
return RawDataToWrExternalImage(nullptr, 0);
|
||||
}
|
||||
mLocked = true;
|
||||
}
|
||||
|
||||
return RawDataToWrExternalImage(mMap.mData,
|
||||
mMap.mStride * mSurface->GetSize().height);
|
||||
}
|
||||
|
||||
void
|
||||
RenderSharedSurfaceTextureHost::Unlock()
|
||||
{
|
||||
if (mLocked) {
|
||||
mSurface->Unmap();
|
||||
mLocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
|
@ -1,37 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_RENDERSHAREDSURFACETEXTUREHOST_H
|
||||
#define MOZILLA_GFX_RENDERSHAREDSURFACETEXTUREHOST_H
|
||||
|
||||
#include "RenderTextureHost.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class SourceSurfaceSharedDataWrapper;
|
||||
}
|
||||
|
||||
namespace wr {
|
||||
|
||||
class RenderSharedSurfaceTextureHost final : public RenderTextureHost
|
||||
{
|
||||
public:
|
||||
explicit RenderSharedSurfaceTextureHost(gfx::SourceSurfaceSharedDataWrapper* aSurface);
|
||||
|
||||
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
|
||||
void Unlock() override;
|
||||
|
||||
private:
|
||||
~RenderSharedSurfaceTextureHost() override;
|
||||
|
||||
RefPtr<gfx::SourceSurfaceSharedDataWrapper> mSurface;
|
||||
gfx::DataSourceSurface::MappedSurface mMap;
|
||||
bool mLocked;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_RENDERSHAREDSURFACETEXTUREHOST_H
|
|
@ -12,11 +12,6 @@
|
|||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
}
|
||||
|
||||
namespace wr {
|
||||
|
||||
class RenderBufferTextureHost;
|
||||
|
@ -29,9 +24,12 @@ class RenderTextureHost
|
|||
public:
|
||||
RenderTextureHost();
|
||||
|
||||
virtual wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) = 0;
|
||||
virtual bool Lock() = 0;
|
||||
virtual void Unlock() = 0;
|
||||
|
||||
virtual RenderBufferTextureHost* AsBufferTextureHost() { return nullptr; }
|
||||
virtual RenderTextureHostOGL* AsTextureHostOGL() { return nullptr; }
|
||||
|
||||
protected:
|
||||
virtual ~RenderTextureHost();
|
||||
};
|
||||
|
|
|
@ -21,9 +21,13 @@ class RenderTextureHostOGL : public RenderTextureHost
|
|||
public:
|
||||
RenderTextureHostOGL();
|
||||
|
||||
virtual void SetGLContext(gl::GLContext* aContext) = 0;
|
||||
|
||||
virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const = 0;
|
||||
virtual GLuint GetGLHandle(uint8_t aChannelIndex) const = 0;
|
||||
|
||||
virtual RenderTextureHostOGL* AsTextureHostOGL() override { return this; }
|
||||
|
||||
protected:
|
||||
virtual ~RenderTextureHostOGL();
|
||||
};
|
||||
|
|
|
@ -22,8 +22,37 @@ wr::WrExternalImage LockExternalImage(void* aObj, wr::WrExternalImageId aId, uin
|
|||
{
|
||||
RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
|
||||
RenderTextureHost* texture = renderer->GetRenderTexture(aId);
|
||||
MOZ_ASSERT(texture);
|
||||
return texture->Lock(aChannelIndex, renderer->mGL);
|
||||
|
||||
if (texture->AsBufferTextureHost()) {
|
||||
RenderBufferTextureHost* bufferTexture = texture->AsBufferTextureHost();
|
||||
MOZ_ASSERT(bufferTexture);
|
||||
|
||||
if (bufferTexture->Lock()) {
|
||||
RenderBufferTextureHost::RenderBufferData data =
|
||||
bufferTexture->GetBufferDataForRender(aChannelIndex);
|
||||
|
||||
return RawDataToWrExternalImage(data.mData, data.mBufferSize);
|
||||
} else {
|
||||
return RawDataToWrExternalImage(nullptr, 0);
|
||||
}
|
||||
} else {
|
||||
// texture handle case
|
||||
RenderTextureHostOGL* textureOGL = texture->AsTextureHostOGL();
|
||||
MOZ_ASSERT(textureOGL);
|
||||
|
||||
textureOGL->SetGLContext(renderer->mGL);
|
||||
gfx::IntSize size = textureOGL->GetSize(aChannelIndex);
|
||||
if (textureOGL->Lock()) {
|
||||
return NativeTextureToWrExternalImage(textureOGL->GetGLHandle(aChannelIndex),
|
||||
0, 0,
|
||||
size.width, size.height);
|
||||
} else {
|
||||
// Just use 0 for the gl handle if the lock() was failed.
|
||||
return NativeTextureToWrExternalImage(0,
|
||||
0, 0,
|
||||
size.width, size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnlockExternalImage(void* aObj, wr::WrExternalImageId aId, uint8_t aChannelIndex)
|
||||
|
|
|
@ -10,7 +10,6 @@ with Files('**'):
|
|||
EXPORTS.mozilla.webrender += [
|
||||
'RenderBufferTextureHost.h',
|
||||
'RendererOGL.h',
|
||||
'RenderSharedSurfaceTextureHost.h',
|
||||
'RenderTextureHost.h',
|
||||
'RenderTextureHostOGL.h',
|
||||
'RenderThread.h',
|
||||
|
@ -24,7 +23,6 @@ UNIFIED_SOURCES += [
|
|||
'Moz2DImageRenderer.cpp',
|
||||
'RenderBufferTextureHost.cpp',
|
||||
'RendererOGL.cpp',
|
||||
'RenderSharedSurfaceTextureHost.cpp',
|
||||
'RenderTextureHost.cpp',
|
||||
'RenderTextureHostOGL.cpp',
|
||||
'RenderThread.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче