mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
f304825fbc
Backed out changeset 49632bc14e27 (bug 900133) Backed out changeset 036780fccc89 (bug 900133) Backed out changeset b8db58f5e209 (bug 893302) Backed out changeset 67c3e4204e44 (bug 893302) Backed out changeset a857a4246dd9 (bug 900133) Backed out changeset e0e2e27af6c1 (bug 881634)
562 lines
15 KiB
C++
562 lines
15 KiB
C++
/* -*- 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 "mozilla/layers/TextureClient.h"
|
|
#include "mozilla/layers/TextureClientOGL.h"
|
|
|
|
#include "mozilla/layers/ImageClient.h"
|
|
#include "mozilla/layers/CanvasClient.h"
|
|
#include "mozilla/layers/ContentClient.h"
|
|
#include "mozilla/layers/ShadowLayers.h"
|
|
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
|
|
#include "GLContext.h"
|
|
#include "BasicLayers.h" // for PaintContext
|
|
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
|
#include "gfxReusableSurfaceWrapper.h"
|
|
#include "gfxPlatform.h"
|
|
#include "mozilla/layers/ImageDataSerializer.h"
|
|
#include "gfx2DGlue.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
using namespace mozilla::gl;
|
|
|
|
namespace mozilla {
|
|
namespace layers {
|
|
|
|
|
|
|
|
|
|
|
|
TextureClient::TextureClient(TextureFlags aFlags)
|
|
: mID(0)
|
|
, mFlags(aFlags)
|
|
{}
|
|
|
|
TextureClient::~TextureClient()
|
|
{}
|
|
|
|
bool
|
|
TextureClient::ShouldDeallocateInDestructor() const
|
|
{
|
|
return IsAllocated() &&
|
|
!IsSharedWithCompositor() &&
|
|
!(GetFlags() & (TEXTURE_DEALLOCATE_HOST|TEXTURE_DEALLOCATE_CLIENT));
|
|
}
|
|
|
|
bool
|
|
ShmemTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor)
|
|
{
|
|
if (!IsAllocated() || GetFormat() == gfx::FORMAT_UNKNOWN) {
|
|
return false;
|
|
}
|
|
|
|
aDescriptor = SurfaceDescriptorShmem(mShmem, GetFormat());
|
|
|
|
return true;
|
|
}
|
|
|
|
ISurfaceAllocator*
|
|
ShmemTextureClient::GetAllocator() const
|
|
{
|
|
return mCompositable->GetForwarder();
|
|
}
|
|
|
|
bool
|
|
ShmemTextureClient::Allocate(uint32_t aSize)
|
|
{
|
|
ipc::SharedMemory::SharedMemoryType memType = OptimalShmemType();
|
|
mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
|
|
return mAllocated;
|
|
}
|
|
|
|
uint8_t*
|
|
ShmemTextureClient::GetBuffer() const
|
|
{
|
|
if (mAllocated) {
|
|
return mShmem.get<uint8_t>();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
size_t
|
|
ShmemTextureClient::GetBufferSize() const
|
|
{
|
|
return mShmem.Size<uint8_t>();
|
|
}
|
|
|
|
ShmemTextureClient::ShmemTextureClient(CompositableClient* aCompositable,
|
|
gfx::SurfaceFormat aFormat)
|
|
: BufferTextureClient(aCompositable, aFormat)
|
|
, mAllocated(false)
|
|
{
|
|
MOZ_COUNT_CTOR(ShmemTextureClient);
|
|
}
|
|
|
|
ShmemTextureClient::~ShmemTextureClient()
|
|
{
|
|
MOZ_COUNT_DTOR(ShmemTextureClient);
|
|
if (ShouldDeallocateInDestructor()) {
|
|
// if the buffer has never been shared we must deallocate it or ir would
|
|
// leak.
|
|
mCompositable->GetForwarder()->DeallocShmem(mShmem);
|
|
}
|
|
}
|
|
|
|
bool
|
|
MemoryTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor)
|
|
{
|
|
if (!IsAllocated() || GetFormat() == gfx::FORMAT_UNKNOWN) {
|
|
return false;
|
|
}
|
|
aDescriptor = SurfaceDescriptorMemory(reinterpret_cast<uintptr_t>(mBuffer),
|
|
GetFormat());
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
MemoryTextureClient::Allocate(uint32_t aSize)
|
|
{
|
|
MOZ_ASSERT(!mBuffer);
|
|
mBuffer = new uint8_t[aSize];
|
|
mBufSize = aSize;
|
|
return true;
|
|
}
|
|
|
|
MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat)
|
|
: BufferTextureClient(aCompositable, aFormat)
|
|
, mBuffer(nullptr)
|
|
, mBufSize(0)
|
|
{
|
|
MOZ_COUNT_CTOR(MemoryTextureClient);
|
|
}
|
|
|
|
MemoryTextureClient::~MemoryTextureClient()
|
|
{
|
|
MOZ_COUNT_DTOR(MemoryTextureClient);
|
|
if (ShouldDeallocateInDestructor()) {
|
|
// if the buffer has never been shared we must deallocate it or ir would
|
|
// leak.
|
|
delete mBuffer;
|
|
}
|
|
}
|
|
|
|
BufferTextureClient::BufferTextureClient(CompositableClient* aCompositable,
|
|
gfx::SurfaceFormat aFormat)
|
|
: TextureClient()
|
|
, mCompositable(aCompositable)
|
|
, mFormat(aFormat)
|
|
{}
|
|
|
|
BufferTextureClient::~BufferTextureClient()
|
|
{}
|
|
|
|
bool
|
|
BufferTextureClient::UpdateSurface(gfxASurface* aSurface)
|
|
{
|
|
MOZ_ASSERT(aSurface);
|
|
|
|
ImageDataSerializer serializer(GetBuffer());
|
|
if (!serializer.IsValid()) {
|
|
return false;
|
|
}
|
|
|
|
RefPtr<gfxImageSurface> surf = serializer.GetAsThebesSurface();
|
|
if (!surf) {
|
|
return false;
|
|
}
|
|
|
|
nsRefPtr<gfxContext> tmpCtx = new gfxContext(surf.get());
|
|
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
|
tmpCtx->DrawSurface(aSurface, gfxSize(serializer.GetSize().width,
|
|
serializer.GetSize().height));
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
BufferTextureClient::AllocateForSurface(gfx::IntSize aSize)
|
|
{
|
|
MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This textureClient cannot use YCbCr data");
|
|
|
|
int bufSize
|
|
= ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat);
|
|
if (!Allocate(bufSize)) {
|
|
return false;
|
|
}
|
|
ImageDataSerializer serializer(GetBuffer());
|
|
serializer.InitializeBufferInfo(aSize, mFormat);
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
BufferTextureClient::UpdateYCbCr(const PlanarYCbCrImage::Data& aData)
|
|
{
|
|
MOZ_ASSERT(mFormat == gfx::FORMAT_YUV, "This textureClient can only use YCbCr data");
|
|
MOZ_ASSERT(!IsImmutable());
|
|
MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
|
|
|
|
YCbCrImageDataSerializer serializer(GetBuffer());
|
|
MOZ_ASSERT(serializer.IsValid());
|
|
if (!serializer.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
|
|
aData.mYSize, aData.mYStride,
|
|
aData.mCbCrSize, aData.mCbCrStride,
|
|
aData.mYSkip, aData.mCbSkip)) {
|
|
NS_WARNING("Failed to copy image data!");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize)
|
|
{
|
|
size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize,
|
|
aCbCrSize);
|
|
if (!Allocate(bufSize)) {
|
|
return false;
|
|
}
|
|
YCbCrImageDataSerializer serializer(GetBuffer());
|
|
serializer.InitializeBufferInfo(aYSize,
|
|
aCbCrSize);
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DeprecatedTextureClient::DeprecatedTextureClient(CompositableForwarder* aForwarder,
|
|
const TextureInfo& aTextureInfo)
|
|
: mForwarder(aForwarder)
|
|
, mTextureInfo(aTextureInfo)
|
|
, mAccessMode(ACCESS_READ_WRITE)
|
|
{
|
|
MOZ_COUNT_CTOR(DeprecatedTextureClient);
|
|
}
|
|
|
|
DeprecatedTextureClient::~DeprecatedTextureClient()
|
|
{
|
|
MOZ_COUNT_DTOR(DeprecatedTextureClient);
|
|
MOZ_ASSERT(mDescriptor.type() == SurfaceDescriptor::T__None, "Need to release surface!");
|
|
}
|
|
|
|
DeprecatedTextureClientShmem::DeprecatedTextureClientShmem(CompositableForwarder* aForwarder,
|
|
const TextureInfo& aTextureInfo)
|
|
: DeprecatedTextureClient(aForwarder, aTextureInfo)
|
|
, mSurface(nullptr)
|
|
, mSurfaceAsImage(nullptr)
|
|
{
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientShmem::ReleaseResources()
|
|
{
|
|
if (mSurface) {
|
|
mSurface = nullptr;
|
|
ShadowLayerForwarder::CloseDescriptor(mDescriptor);
|
|
}
|
|
|
|
if (mTextureInfo.mTextureFlags & TEXTURE_DEALLOCATE_HOST) {
|
|
mDescriptor = SurfaceDescriptor();
|
|
return;
|
|
}
|
|
|
|
if (IsSurfaceDescriptorValid(mDescriptor)) {
|
|
mForwarder->DestroySharedSurface(&mDescriptor);
|
|
mDescriptor = SurfaceDescriptor();
|
|
}
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientShmem::EnsureAllocated(gfx::IntSize aSize,
|
|
gfxASurface::gfxContentType aContentType)
|
|
{
|
|
if (aSize != mSize ||
|
|
aContentType != mContentType ||
|
|
!IsSurfaceDescriptorValid(mDescriptor)) {
|
|
ReleaseResources();
|
|
|
|
mContentType = aContentType;
|
|
mSize = aSize;
|
|
|
|
if (!mForwarder->AllocSurfaceDescriptor(gfxIntSize(mSize.width, mSize.height),
|
|
mContentType, &mDescriptor)) {
|
|
NS_WARNING("creating SurfaceDescriptor failed!");
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientShmem::SetDescriptor(const SurfaceDescriptor& aDescriptor)
|
|
{
|
|
if (IsSurfaceDescriptorValid(aDescriptor)) {
|
|
ReleaseResources();
|
|
mDescriptor = aDescriptor;
|
|
} else {
|
|
EnsureAllocated(mSize, mContentType);
|
|
}
|
|
|
|
mSurface = nullptr;
|
|
|
|
NS_ASSERTION(mDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc ||
|
|
mDescriptor.type() == SurfaceDescriptor::TShmem ||
|
|
mDescriptor.type() == SurfaceDescriptor::TMemoryImage ||
|
|
mDescriptor.type() == SurfaceDescriptor::TRGBImage,
|
|
"Invalid surface descriptor");
|
|
}
|
|
|
|
gfxASurface*
|
|
DeprecatedTextureClientShmem::GetSurface()
|
|
{
|
|
if (!mSurface) {
|
|
if (!IsSurfaceDescriptorValid(mDescriptor)) {
|
|
return nullptr;
|
|
}
|
|
MOZ_ASSERT(mAccessMode == ACCESS_READ_WRITE || mAccessMode == ACCESS_READ_ONLY);
|
|
OpenMode mode = mAccessMode == ACCESS_READ_WRITE
|
|
? OPEN_READ_WRITE
|
|
: OPEN_READ_ONLY;
|
|
mSurface = ShadowLayerForwarder::OpenDescriptor(mode, mDescriptor);
|
|
}
|
|
|
|
return mSurface.get();
|
|
}
|
|
|
|
|
|
gfx::DrawTarget*
|
|
DeprecatedTextureClientShmem::LockDrawTarget()
|
|
{
|
|
if (mDrawTarget) {
|
|
return mDrawTarget;
|
|
}
|
|
|
|
gfxASurface* surface = GetSurface();
|
|
mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
|
|
|
|
return mDrawTarget;
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientShmem::Unlock()
|
|
{
|
|
mSurface = nullptr;
|
|
mSurfaceAsImage = nullptr;
|
|
mDrawTarget = nullptr;
|
|
|
|
ShadowLayerForwarder::CloseDescriptor(mDescriptor);
|
|
}
|
|
|
|
gfxImageSurface*
|
|
DeprecatedTextureClientShmem::LockImageSurface()
|
|
{
|
|
if (!mSurfaceAsImage) {
|
|
mSurfaceAsImage = GetSurface()->GetAsImageSurface();
|
|
}
|
|
|
|
return mSurfaceAsImage.get();
|
|
}
|
|
|
|
DeprecatedTextureClientTile::DeprecatedTextureClientTile(const DeprecatedTextureClientTile& aOther)
|
|
: DeprecatedTextureClient(aOther.mForwarder, aOther.mTextureInfo)
|
|
, mSurface(aOther.mSurface)
|
|
{}
|
|
|
|
DeprecatedTextureClientTile::~DeprecatedTextureClientTile()
|
|
{}
|
|
|
|
void
|
|
DeprecatedTextureClientShmemYCbCr::ReleaseResources()
|
|
{
|
|
GetForwarder()->DestroySharedSurface(&mDescriptor);
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientShmemYCbCr::SetDescriptor(const SurfaceDescriptor& aDescriptor)
|
|
{
|
|
MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TYCbCrImage);
|
|
|
|
if (IsSurfaceDescriptorValid(mDescriptor)) {
|
|
GetForwarder()->DestroySharedSurface(&mDescriptor);
|
|
}
|
|
mDescriptor = aDescriptor;
|
|
MOZ_ASSERT(IsSurfaceDescriptorValid(mDescriptor));
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientShmemYCbCr::SetDescriptorFromReply(const SurfaceDescriptor& aDescriptor)
|
|
{
|
|
MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TYCbCrImage);
|
|
DeprecatedSharedPlanarYCbCrImage* shYCbCr = DeprecatedSharedPlanarYCbCrImage::FromSurfaceDescriptor(aDescriptor);
|
|
if (shYCbCr) {
|
|
shYCbCr->Release();
|
|
mDescriptor = SurfaceDescriptor();
|
|
} else {
|
|
SetDescriptor(aDescriptor);
|
|
}
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientShmemYCbCr::EnsureAllocated(gfx::IntSize aSize,
|
|
gfxASurface::gfxContentType aType)
|
|
{
|
|
NS_RUNTIMEABORT("not enough arguments to do this (need both Y and CbCr sizes)");
|
|
}
|
|
|
|
|
|
DeprecatedTextureClientTile::DeprecatedTextureClientTile(CompositableForwarder* aForwarder,
|
|
const TextureInfo& aTextureInfo)
|
|
: DeprecatedTextureClient(aForwarder, aTextureInfo)
|
|
, mSurface(nullptr)
|
|
{
|
|
mTextureInfo.mDeprecatedTextureHostFlags = TEXTURE_HOST_TILED;
|
|
}
|
|
|
|
void
|
|
DeprecatedTextureClientTile::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType)
|
|
{
|
|
if (!mSurface ||
|
|
mSurface->Format() != gfxPlatform::GetPlatform()->OptimalFormatForContent(aType)) {
|
|
gfxImageSurface* tmpTile = new gfxImageSurface(gfxIntSize(aSize.width, aSize.height),
|
|
gfxPlatform::GetPlatform()->OptimalFormatForContent(aType),
|
|
aType != gfxASurface::CONTENT_COLOR);
|
|
mSurface = new gfxReusableSurfaceWrapper(tmpTile);
|
|
mContentType = aType;
|
|
}
|
|
}
|
|
|
|
gfxImageSurface*
|
|
DeprecatedTextureClientTile::LockImageSurface()
|
|
{
|
|
// Use the gfxReusableSurfaceWrapper, which will reuse the surface
|
|
// if the compositor no longer has a read lock, otherwise the surface
|
|
// will be copied into a new writable surface.
|
|
gfxImageSurface* writableSurface = nullptr;
|
|
mSurface = mSurface->GetWritable(&writableSurface);
|
|
return writableSurface;
|
|
}
|
|
|
|
// XXX - All the code below can be removed as soon as we remove
|
|
// DeprecatedImageClientSingle (which has already been ported to the new
|
|
// textures).
|
|
|
|
bool AutoLockShmemClient::Update(Image* aImage,
|
|
uint32_t aContentFlags,
|
|
gfxASurface *aSurface)
|
|
{
|
|
if (!aImage) {
|
|
return false;
|
|
}
|
|
|
|
gfxIntSize size = aImage->GetSize();
|
|
|
|
gfxASurface::gfxContentType contentType = aSurface->GetContentType();
|
|
bool isOpaque = (aContentFlags & Layer::CONTENT_OPAQUE);
|
|
if (contentType != gfxASurface::CONTENT_ALPHA &&
|
|
isOpaque) {
|
|
contentType = gfxASurface::CONTENT_COLOR;
|
|
}
|
|
mDeprecatedTextureClient->EnsureAllocated(gfx::IntSize(size.width, size.height), contentType);
|
|
|
|
OpenMode mode = mDeprecatedTextureClient->GetAccessMode() == DeprecatedTextureClient::ACCESS_READ_WRITE
|
|
? OPEN_READ_WRITE
|
|
: OPEN_READ_ONLY;
|
|
nsRefPtr<gfxASurface> tmpASurface =
|
|
ShadowLayerForwarder::OpenDescriptor(mode,
|
|
*mDeprecatedTextureClient->LockSurfaceDescriptor());
|
|
if (!tmpASurface) {
|
|
return false;
|
|
}
|
|
nsRefPtr<gfxContext> tmpCtx = new gfxContext(tmpASurface.get());
|
|
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
|
tmpCtx->DrawSurface(aSurface, gfxSize(size.width, size.height));
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
AutoLockYCbCrClient::Update(PlanarYCbCrImage* aImage)
|
|
{
|
|
MOZ_ASSERT(aImage);
|
|
MOZ_ASSERT(mDescriptor);
|
|
|
|
const PlanarYCbCrImage::Data *data = aImage->GetData();
|
|
NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
|
|
if (!data) {
|
|
return false;
|
|
}
|
|
|
|
if (!EnsureDeprecatedTextureClient(aImage)) {
|
|
return false;
|
|
}
|
|
|
|
ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
|
|
|
|
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
|
|
if (!serializer.CopyData(data->mYChannel, data->mCbChannel, data->mCrChannel,
|
|
data->mYSize, data->mYStride,
|
|
data->mCbCrSize, data->mCbCrStride,
|
|
data->mYSkip, data->mCbSkip)) {
|
|
NS_WARNING("Failed to copy image data!");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AutoLockYCbCrClient::EnsureDeprecatedTextureClient(PlanarYCbCrImage* aImage)
|
|
{
|
|
MOZ_ASSERT(aImage);
|
|
if (!aImage) {
|
|
return false;
|
|
}
|
|
|
|
const PlanarYCbCrImage::Data *data = aImage->GetData();
|
|
NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
|
|
if (!data) {
|
|
return false;
|
|
}
|
|
|
|
bool needsAllocation = false;
|
|
if (mDescriptor->type() != SurfaceDescriptor::TYCbCrImage) {
|
|
needsAllocation = true;
|
|
} else {
|
|
ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
|
|
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
|
|
if (serializer.GetYSize() != data->mYSize ||
|
|
serializer.GetCbCrSize() != data->mCbCrSize) {
|
|
needsAllocation = true;
|
|
}
|
|
}
|
|
|
|
if (!needsAllocation) {
|
|
return true;
|
|
}
|
|
|
|
mDeprecatedTextureClient->ReleaseResources();
|
|
|
|
ipc::SharedMemory::SharedMemoryType shmType = OptimalShmemType();
|
|
size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(data->mYSize,
|
|
data->mCbCrSize);
|
|
ipc::Shmem shmem;
|
|
if (!mDeprecatedTextureClient->GetForwarder()->AllocUnsafeShmem(size, shmType, &shmem)) {
|
|
return false;
|
|
}
|
|
|
|
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
|
|
serializer.InitializeBufferInfo(data->mYSize,
|
|
data->mCbCrSize);
|
|
|
|
*mDescriptor = YCbCrImage(shmem, 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
}
|
|
}
|