mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1072501: Unmap file mapping on source surface destruction. r=jrmuizel
This commit is contained in:
parent
4d9936e89e
commit
548046553b
@ -28,6 +28,8 @@ public:
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
static
|
||||
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
|
||||
|
||||
@ -63,6 +65,8 @@ public:
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
static
|
||||
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
@ -101,6 +105,10 @@ public:
|
||||
virtual ~ShmemDIBTextureData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ShmemDIBTextureData);
|
||||
|
||||
// The host side has its own references and handles to this data, we can
|
||||
// safely clear ours.
|
||||
DeallocateData();
|
||||
}
|
||||
|
||||
HANDLE mFileMapping;
|
||||
@ -115,31 +123,6 @@ DIBTextureData::BorrowDrawTarget()
|
||||
return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
|
||||
}
|
||||
|
||||
bool
|
||||
DIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
RefPtr<gfxImageSurface> imgSurf = mSurface->GetAsImageSurface();
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface sourceMap;
|
||||
srcSurf->Map(DataSourceSurface::READ, &sourceMap);
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
memcpy(imgSurf->Data() + imgSurf->Stride() * y,
|
||||
sourceMap.mData + sourceMap.mStride * y,
|
||||
srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
|
||||
}
|
||||
|
||||
srcSurf->Unmap();
|
||||
return true;
|
||||
}
|
||||
|
||||
DIBTextureData*
|
||||
DIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
@ -192,6 +175,34 @@ MemoryDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
|
||||
return new MemoryDIBTextureData(aSize, aFormat, surface);
|
||||
}
|
||||
|
||||
bool
|
||||
MemoryDIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
RefPtr<gfxImageSurface> imgSurf = mSurface->GetAsImageSurface();
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface sourceMap;
|
||||
if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) {
|
||||
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
memcpy(imgSurf->Data() + imgSurf->Stride() * y,
|
||||
sourceMap.mData + sourceMap.mStride * y,
|
||||
srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
|
||||
}
|
||||
|
||||
srcSurf->Unmap();
|
||||
return true;
|
||||
}
|
||||
|
||||
TextureData*
|
||||
ShmemDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
@ -203,6 +214,46 @@ ShmemDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
return ShmemDIBTextureData::Create(mSize, mFormat, aAllocator);
|
||||
}
|
||||
|
||||
bool
|
||||
ShmemDIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface sourceMap;
|
||||
if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) {
|
||||
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
GdiFlush();
|
||||
|
||||
uint32_t stride = mSize.width * BytesPerPixel(mFormat);
|
||||
uint8_t* data = (uint8_t*)::MapViewOfFile(mFileMapping, FILE_MAP_WRITE, 0, 0, stride * mSize.height);
|
||||
|
||||
if (!data) {
|
||||
gfxCriticalError() << "Failed to map view of file for UpdateFromSurface.";
|
||||
srcSurf->Unmap();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
memcpy(data + stride * y,
|
||||
sourceMap.mData + sourceMap.mStride * y,
|
||||
srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
|
||||
}
|
||||
|
||||
::UnmapViewOfFile(data);
|
||||
|
||||
srcSurf->Unmap();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ShmemDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
@ -229,14 +280,6 @@ ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t* data = (uint8_t*)::MapViewOfFile(fileMapping, FILE_MAP_WRITE | FILE_MAP_READ,
|
||||
0, 0, aSize.width * aSize.height
|
||||
* BytesPerPixel(aFormat));
|
||||
|
||||
memset(data, 0x80, aSize.width * aSize.height * BytesPerPixel(aFormat));
|
||||
|
||||
::UnmapViewOfFile(fileMapping);
|
||||
|
||||
BITMAPV4HEADER header;
|
||||
memset(&header, 0, sizeof(BITMAPV4HEADER));
|
||||
header.bV4Size = sizeof(BITMAPV4HEADER);
|
||||
@ -249,7 +292,11 @@ ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
header.bV4GreenMask = 0x0000FF00;
|
||||
header.bV4BlueMask = 0x000000FF;
|
||||
|
||||
HDC dc = ::CreateCompatibleDC(::GetDC(NULL));
|
||||
HDC nulldc = ::GetDC(NULL);
|
||||
|
||||
HDC dc = ::CreateCompatibleDC(nulldc);
|
||||
|
||||
::ReleaseDC(nullptr, nulldc);
|
||||
|
||||
if (!dc) {
|
||||
::CloseHandle(fileMapping);
|
||||
@ -264,7 +311,7 @@ ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
|
||||
if (!bitmap) {
|
||||
gfxCriticalError() << "Failed to create DIB section for a bitmap of size "
|
||||
<< aSize;
|
||||
<< aSize << " and mapSize " << mapSize;
|
||||
::CloseHandle(fileMapping);
|
||||
::DeleteDC(dc);
|
||||
return nullptr;
|
||||
@ -392,6 +439,14 @@ TextureHostFileMapping::~TextureHostFileMapping()
|
||||
::CloseHandle(mFileMapping);
|
||||
}
|
||||
|
||||
UserDataKey kFileMappingKey;
|
||||
|
||||
static void UnmapFileData(void* aData)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
::UnmapViewOfFile(aData);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostFileMapping::UpdatedInternal(const nsIntRegion* aRegion)
|
||||
{
|
||||
@ -410,14 +465,14 @@ TextureHostFileMapping::UpdatedInternal(const nsIntRegion* aRegion)
|
||||
if (data) {
|
||||
RefPtr<DataSourceSurface> surf = Factory::CreateWrappingDataSourceSurface(data, mSize.width * BytesPerPixel(mFormat), mSize, mFormat);
|
||||
|
||||
surf->AddUserData(&kFileMappingKey, data, UnmapFileData);
|
||||
|
||||
if (!mTextureSource->Update(surf, const_cast<nsIntRegion*>(aRegion))) {
|
||||
mTextureSource = nullptr;
|
||||
}
|
||||
} else {
|
||||
mTextureSource = nullptr;
|
||||
}
|
||||
|
||||
::UnmapViewOfFile(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,8 +30,6 @@ public:
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
static
|
||||
|
@ -732,7 +732,6 @@ TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
|
||||
}
|
||||
|
||||
if (!data && aFormat == SurfaceFormat::B8G8R8X8 &&
|
||||
aAllocator->IsSameProcess() &&
|
||||
moz2DBackend == gfx::BackendType::CAIRO &&
|
||||
NS_IsMainThread()) {
|
||||
data = DIBTextureData::Create(aSize, aFormat, aAllocator);
|
||||
|
Loading…
Reference in New Issue
Block a user