Bug 938591 - Use texture flags in DataTextureSource + D3D9/11 fixes. r=nrc

This commit is contained in:
Nicolas Silva 2014-01-07 17:20:11 +01:00
Родитель 4d8b6b278e
Коммит e8b4b086ed
22 изменённых файлов: 446 добавлений и 112 удалений

Просмотреть файл

@ -269,10 +269,12 @@ struct TextureInfo
*
* See ShadowLayerForwarder::OpenDescriptor for example.
*/
enum OpenMode {
OPEN_READ_ONLY = 0x1,
OPEN_READ_WRITE = 0x2
};
typedef uint32_t OpenMode;
const OpenMode OPEN_READ = 0x1;
const OpenMode OPEN_WRITE = 0x2;
const OpenMode OPEN_READ_WRITE = OPEN_READ|OPEN_WRITE;
const OpenMode OPEN_READ_ONLY = OPEN_READ;
const OpenMode OPEN_WRITE_ONLY = OPEN_WRITE;
// The kinds of mask texture a shader can support
// We rely on the items in this enum being sequential

Просмотреть файл

@ -32,6 +32,7 @@ public:
bool IsValid() const;
uint8_t* GetData();
uint32_t GetStride() const;
gfx::IntSize GetSize() const;
gfx::SurfaceFormat GetFormat() const;
TemporaryRef<gfx::DataSourceSurface> GetAsSurface();
@ -39,7 +40,6 @@ public:
TemporaryRef<gfx::DrawTarget> GetAsDrawTarget();
protected:
uint32_t GetStride() const;
ImageDataSerializerBase(uint8_t* aData)
: mData(aData) {}

Просмотреть файл

@ -44,7 +44,6 @@ public:
}
virtual bool Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion = nullptr,
gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE
{

Просмотреть файл

@ -77,7 +77,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
bufferCreated = true;
}
if (!mBuffer->Lock(OPEN_READ_WRITE)) {
if (!mBuffer->Lock(OPEN_WRITE_ONLY)) {
return;
}

Просмотреть файл

@ -207,11 +207,11 @@ CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat,
#ifdef XP_WIN
LayersBackend parentBackend = GetForwarder()->GetCompositorBackendType();
// XXX[nrc] uncomment once we have new texture clients for windows
if (parentBackend == LAYERS_D3D11 && gfxWindowsPlatform::GetPlatform()->GetD2DDevice() &&
!(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) {
//result = new TextureClientD3D11(GetForwarder(), GetTextureInfo());
result = new TextureClientD3D11(aFormat, aTextureFlags);
}
// XXX[nrc] uncomment once we have new texture clients for D3D9
if (parentBackend == LAYERS_D3D9 &&
!GetForwarder()->ForwardsToDifferentProcess() &&
!(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) {

Просмотреть файл

@ -32,10 +32,13 @@
#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
#include "nsISupportsImpl.h" // for Image::Release, etc
#include "nsRect.h" // for nsIntRect
#include "mozilla/gfx/2D.h"
#ifdef MOZ_WIDGET_GONK
#include "GrallocImages.h"
#endif
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
@ -177,7 +180,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
bufferCreated = true;
}
if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) {
if (!mFrontBuffer->Lock(OPEN_WRITE_ONLY)) {
return false;
}
bool status = mFrontBuffer->AsTextureClientYCbCr()->UpdateYCbCr(*data);
@ -233,18 +236,29 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
if (!mFrontBuffer) {
gfxImageFormat format
= gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType());
mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format),
TEXTURE_FLAGS_DEFAULT);
MOZ_ASSERT(mFrontBuffer->AsTextureClientSurface());
mFrontBuffer->AsTextureClientSurface()->AllocateForSurface(size);
mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
mTextureFlags);
MOZ_ASSERT(mFrontBuffer->AsTextureClientDrawTarget());
if (!mFrontBuffer->AsTextureClientDrawTarget()->AllocateForSurface(size)) {
mFrontBuffer = nullptr;
return false;
}
bufferCreated = true;
}
if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) {
if (!mFrontBuffer->Lock(OPEN_WRITE_ONLY)) {
return false;
}
bool status = mFrontBuffer->AsTextureClientSurface()->UpdateSurface(surface);
{
// We must not keep a reference to the DrawTarget after it has been unlocked.
RefPtr<DrawTarget> dt = mFrontBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget();
RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, surface);
MOZ_ASSERT(source.get());
dt->CopySurface(source, IntRect(IntPoint(), source->GetSize()), IntPoint());
}
mFrontBuffer->Unlock();
if (bufferCreated) {
@ -254,12 +268,8 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
}
}
if (status) {
GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
GetForwarder()->UseTexture(this, mFrontBuffer);
} else {
return false;
}
GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
GetForwarder()->UseTexture(this, mFrontBuffer);
}
UpdatePictureRect(image->GetPictureRect());

Просмотреть файл

@ -337,7 +337,7 @@ ShmemTextureClient::GetAllocator() const
bool
ShmemTextureClient::Allocate(uint32_t aSize)
{
MOZ_ASSERT(IsValid());
MOZ_ASSERT(mValid);
ipc::SharedMemory::SharedMemoryType memType = OptimalShmemType();
mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
return mAllocated;
@ -433,6 +433,8 @@ BufferTextureClient::BufferTextureClient(CompositableClient* aCompositable,
: TextureClient(aFlags)
, mCompositable(aCompositable)
, mFormat(aFormat)
, mUsingFallbackDrawTarget(false)
, mLocked(false)
{}
BufferTextureClient::~BufferTextureClient()
@ -451,10 +453,13 @@ BufferTextureClient::UpdateSurface(gfxASurface* aSurface)
}
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
RefPtr<DrawTarget> dt = serializer.GetAsDrawTarget();
RefPtr<DrawTarget> dt = GetAsDrawTarget();
RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aSurface);
dt->CopySurface(source, IntRect(IntPoint(), serializer.GetSize()), IntPoint());
// XXX - if the Moz2D backend is D2D, we would be much better off memcpying
// the content of the surface directly because with D2D, GetAsDrawTarget is
// very expensive.
} else {
RefPtr<gfxImageSurface> surf = serializer.GetAsThebesSurface();
if (!surf) {
@ -467,7 +472,6 @@ BufferTextureClient::UpdateSurface(gfxASurface* aSurface)
serializer.GetSize().height));
}
if (TextureRequiresLocking(mFlags) && !ImplementsLocking()) {
// We don't have support for proper locking yet, so we'll
// have to be immutable instead.
@ -496,6 +500,7 @@ BufferTextureClient::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFla
{
MOZ_ASSERT(IsValid());
MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This textureClient cannot use YCbCr data");
MOZ_ASSERT(aSize.width * aSize.height);
int bufSize
= ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat);
@ -517,13 +522,86 @@ TemporaryRef<gfx::DrawTarget>
BufferTextureClient::GetAsDrawTarget()
{
MOZ_ASSERT(IsValid());
// XXX - uncomment when ContentClient's locking is fixed
// MOZ_ASSERT(mLocked);
if (mDrawTarget) {
return mDrawTarget;
}
ImageDataSerializer serializer(GetBuffer());
if (!serializer.IsValid()) {
return nullptr;
}
return serializer.GetAsDrawTarget();
MOZ_ASSERT(mUsingFallbackDrawTarget == false);
mDrawTarget = serializer.GetAsDrawTarget();
if (mDrawTarget) {
return mDrawTarget;
}
// fallback path, probably because the Moz2D backend can't create a
// DrawTarget around raw memory. This is going to be slow :(
mDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
serializer.GetSize(), serializer.GetFormat());
if (!mDrawTarget) {
return nullptr;
}
mUsingFallbackDrawTarget = true;
if (mOpenMode & OPEN_READ) {
RefPtr<DataSourceSurface> surface = serializer.GetAsSurface();
IntRect rect(0, 0, surface->GetSize().width, surface->GetSize().height);
mDrawTarget->CopySurface(surface, rect, IntPoint(0,0));
}
return mDrawTarget;
}
bool
BufferTextureClient::Lock(OpenMode aMode)
{
MOZ_ASSERT(!mLocked);
mOpenMode = aMode;
mLocked = true;
return true;
}
void
BufferTextureClient::Unlock()
{
MOZ_ASSERT(mLocked);
mLocked = false;
if (!mDrawTarget) {
mUsingFallbackDrawTarget = false;
return;
}
mDrawTarget->Flush();
if (mUsingFallbackDrawTarget && (mOpenMode & OPEN_WRITE)) {
// When we are using a fallback DrawTarget, it means we could not create
// a DrawTarget wrapping the TextureClient's shared memory. In this scenario
// we need to put the content of the fallback draw target back into our shared
// memory.
RefPtr<SourceSurface> snapshot = mDrawTarget->Snapshot();
RefPtr<DataSourceSurface> surface = snapshot->GetDataSurface();
ImageDataSerializer serializer(GetBuffer());
if (!serializer.IsValid() || serializer.GetSize() != surface->GetSize()) {
NS_WARNING("Could not write the data back into the texture.");
mDrawTarget = nullptr;
mUsingFallbackDrawTarget = false;
return;
}
MOZ_ASSERT(surface->GetSize() == serializer.GetSize());
MOZ_ASSERT(surface->GetFormat() == serializer.GetFormat());
int bpp = BytesPerPixel(surface->GetFormat());
for (int i = 0; i < surface->GetSize().height; ++i) {
memcpy(serializer.GetData() + i*serializer.GetStride(),
surface->GetData() + i*surface->Stride(),
surface->GetSize().width * bpp);
}
}
mDrawTarget = nullptr;
mUsingFallbackDrawTarget = false;
}
bool

Просмотреть файл

@ -309,6 +309,10 @@ public:
virtual gfx::IntSize GetSize() const { return mSize; }
virtual bool Lock(OpenMode aMode) MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
// TextureClientSurface
virtual TextureClientSurface* AsTextureClientSurface() MOZ_OVERRIDE { return this; }
@ -347,9 +351,13 @@ public:
virtual size_t GetBufferSize() const = 0;
protected:
RefPtr<gfx::DrawTarget> mDrawTarget;
CompositableClient* mCompositable;
gfx::SurfaceFormat mFormat;
gfx::IntSize mSize;
OpenMode mOpenMode;
bool mUsingFallbackDrawTarget;
bool mLocked;
};
/**

Просмотреть файл

@ -73,6 +73,10 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
RefPtr<TexturedEffect> effect =
CreateTexturedEffect(source, sourceOnWhite, aFilter);
if (!effect) {
return;
}
aEffectChain.mPrimaryEffect = effect;
nsIntRegion tmpRegion;

Просмотреть файл

@ -371,7 +371,7 @@ BufferTextureHost::Updated(const nsIntRegion* aRegion)
}
if (GetFlags() & TEXTURE_IMMEDIATE_UPLOAD) {
DebugOnly<bool> result = MaybeUpload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr);
MOZ_ASSERT(result);
NS_WARN_IF_FALSE(result, "Failed to upload a texture");
}
}
@ -381,7 +381,11 @@ BufferTextureHost::SetCompositor(Compositor* aCompositor)
if (mCompositor == aCompositor) {
return;
}
DeallocateDeviceData();
RefPtr<NewTextureSource> it = mFirstSource;
while (it) {
it->SetCompositor(aCompositor);
it = it->GetNextSibling();
}
mCompositor = aCompositor;
}
@ -475,7 +479,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
if (!mFirstSource) {
mFirstSource = mCompositor->CreateDataTextureSource(mFlags);
}
mFirstSource->Update(surf, mFlags, aRegion);
mFirstSource->Update(surf, aRegion);
return true;
}
@ -520,9 +524,9 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
gfx::FORMAT_A8);
// We don't support partial updates for Y U V textures
NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
if (!srcY->Update(tempY, mFlags) ||
!srcU->Update(tempCb, mFlags) ||
!srcV->Update(tempCr, mFlags)) {
if (!srcY->Update(tempY) ||
!srcU->Update(tempCb) ||
!srcV->Update(tempCr)) {
NS_WARNING("failed to update the DataTextureSource");
return false;
}
@ -542,7 +546,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
return false;
}
if (!mFirstSource->Update(surf.get(), mFlags, aRegion)) {
if (!mFirstSource->Update(surf.get(), aRegion)) {
NS_WARNING("failed to update the DataTextureSource");
return false;
}

Просмотреть файл

@ -149,6 +149,8 @@ public:
*/
virtual void DeallocateDeviceData() = 0;
virtual void SetCompositor(Compositor* aCompositor) {}
void SetNextSibling(NewTextureSource* aTexture)
{
mNextSibling = aTexture;
@ -195,7 +197,6 @@ public:
* the device texture it uploads to internally.
*/
virtual bool Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion = nullptr,
gfx::IntPoint* aSrcOffset = nullptr) = 0;

Просмотреть файл

@ -516,6 +516,11 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EFFECT_MASK].get());
TextureSourceD3D11* source = maskEffect->mMaskTexture->AsSourceD3D11();
if (!source) {
NS_WARNING("Missing texture source!");
return;
}
RefPtr<ID3D11ShaderResourceView> view;
mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
@ -562,6 +567,11 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
TextureSourceD3D11* source = texturedEffect->mTexture->AsSourceD3D11();
if (!source) {
NS_WARNING("Missing texture source!");
return;
}
RefPtr<ID3D11ShaderResourceView> view;
mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
@ -586,6 +596,18 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
const int Y = 0, Cb = 1, Cr = 2;
TextureSource* source = ycbcrEffect->mTexture;
if (!source) {
NS_WARNING("No texture to composite");
return;
}
if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) {
// This can happen if we failed to upload the textures, most likely
// because of unsupported dimensions (we don't tile YCbCr textures).
return;
}
TextureSourceD3D11* sourceY = source->GetSubSource(Y)->AsSourceD3D11();
TextureSourceD3D11* sourceCb = source->GetSubSource(Cb)->AsSourceD3D11();
TextureSourceD3D11* sourceCr = source->GetSubSource(Cr)->AsSourceD3D11();
@ -610,6 +632,12 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
TextureSourceD3D11* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceD3D11();
TextureSourceD3D11* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceD3D11();
if (!sourceOnWhite || !sourceOnBlack) {
NS_WARNING("Missing texture source(s)!");
return;
}
SetSamplerForFilter(effectComponentAlpha->mFilter);
mVSConstants.textureCoords = effectComponentAlpha->mTextureCoords;

Просмотреть файл

@ -62,12 +62,37 @@ GetTileRectD3D11(uint32_t aID, IntSize aSize, uint32_t aMaxSize)
DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat,
CompositorD3D11* aCompositor)
: mFormat(aFormat)
, mCompositor(aCompositor)
: mCompositor(aCompositor)
, mFormat(aFormat)
, mFlags(0)
, mCurrentTile(0)
, mIsTiled(false)
, mIterating(false)
{
MOZ_COUNT_CTOR(DataTextureSourceD3D11);
}
DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat,
CompositorD3D11* aCompositor,
ID3D11Texture2D* aTexture)
: mCompositor(aCompositor)
, mFormat(aFormat)
, mFlags(0)
, mCurrentTile(0)
, mIsTiled(false)
, mIterating(false)
{
MOZ_COUNT_CTOR(DataTextureSourceD3D11);
mTexture = aTexture;
D3D11_TEXTURE2D_DESC desc;
aTexture->GetDesc(&desc);
mSize = IntSize(desc.Width, desc.Height);
}
DataTextureSourceD3D11::~DataTextureSourceD3D11()
{
MOZ_COUNT_DTOR(DataTextureSourceD3D11);
@ -116,6 +141,15 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
return result;
}
TextureClientD3D11::TextureClientD3D11(gfx::SurfaceFormat aFormat, TextureFlags aFlags)
: TextureClient(aFlags)
, mFormat(aFormat)
, mIsLocked(false)
{}
TextureClientD3D11::~TextureClientD3D11()
{}
bool
TextureClientD3D11::Lock(OpenMode aMode)
{
@ -129,50 +163,108 @@ void
TextureClientD3D11::Unlock()
{
MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
if (mDrawTarget) {
mDrawTarget->Flush();
mDrawTarget = nullptr;
}
UnlockD3DTexture(mTexture.get());
mIsLocked = false;
}
DataTextureSourceD3D11::DataTextureSourceD3D11(ID3D11Texture2D* aTexture,
SurfaceFormat aFormat)
: mFormat(aFormat)
TemporaryRef<DrawTarget>
TextureClientD3D11::GetAsDrawTarget()
{
mTexture = aTexture;
D3D11_TEXTURE2D_DESC desc;
aTexture->GetDesc(&desc);
MOZ_ASSERT(mIsLocked, "Calling TextureClient::GetAsDrawTarget without locking :(");
mSize = IntSize(desc.Width, desc.Height);
if (mDrawTarget) {
return mDrawTarget;
}
mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, mFormat);
return mDrawTarget;
}
bool
TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags)
{
mSize = aSize;
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
CD3D10_TEXTURE2D_DESC newDesc(SurfaceFormatToDXGIFormat(mFormat),
aSize.width, aSize.height, 1, 1,
D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
if (FAILED(hr)) {
LOGD3D11("Error creating texture for client!");
return false;
}
return true;
}
bool
TextureClientD3D11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
if (!IsAllocated()) {
return false;
}
RefPtr<IDXGIResource> resource;
mTexture->QueryInterface((IDXGIResource**)byRef(resource));
HANDLE sharedHandle;
HRESULT hr = resource->GetSharedHandle(&sharedHandle);
if (FAILED(hr)) {
LOGD3D11("Error getting shared handle for texture.");
return false;
}
aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat);
return true;
}
DXGITextureHostD3D11::DXGITextureHostD3D11(TextureFlags aFlags,
const SurfaceDescriptorD3D10& aDescriptor)
: TextureHost(aFlags)
, mHandle(aDescriptor.handle())
, mFormat(aDescriptor.hasAlpha() ? FORMAT_B8G8R8A8 : FORMAT_B8G8R8X8)
, mFormat(aDescriptor.format())
, mIsLocked(false)
{}
ID3D11Device*
DXGITextureHostD3D11::GetDevice()
{
return mCompositor ? mCompositor->GetDevice() : nullptr;
}
void
DXGITextureHostD3D11::SetCompositor(Compositor* aCompositor)
{
CompositorD3D11 *d3dCompositor = static_cast<CompositorD3D11*>(aCompositor);
mDevice = d3dCompositor ? d3dCompositor->GetDevice() : nullptr;
mCompositor = static_cast<CompositorD3D11*>(aCompositor);
}
bool
DXGITextureHostD3D11::Lock()
{
if (!mDevice) {
if (!GetDevice()) {
NS_WARNING("trying to lock a TextureHost without a D3D device");
return false;
}
if (!mTextureSource) {
RefPtr<ID3D11Texture2D> tex;
mDevice->OpenSharedResource((HANDLE)mHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)byRef(tex));
HRESULT hr = GetDevice()->OpenSharedResource((HANDLE)mHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)byRef(tex));
if (FAILED(hr)) {
NS_WARNING("Failed to open shared texture");
return false;
}
mTextureSource = new DataTextureSourceD3D11(tex, mFormat);
mTextureSource = new DataTextureSourceD3D11(mFormat, mCompositor, tex);
D3D11_TEXTURE2D_DESC desc;
tex->GetDesc(&desc);
mSize = IntSize(desc.Width, desc.Height);
@ -200,7 +292,6 @@ DXGITextureHostD3D11::GetTextureSources()
bool
DataTextureSourceD3D11::Update(DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion,
IntPoint* aSrcOffset)
{
@ -218,25 +309,32 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface,
DXGI_FORMAT dxgiFormat = SurfaceFormatToDXGIFormat(aSurface->GetFormat());
mSize = aSurface->GetSize();
mFormat = aSurface->GetFormat();
CD3D11_TEXTURE2D_DESC desc(dxgiFormat, mSize.width, mSize.height,
1, 1, D3D11_BIND_SHADER_RESOURCE,
D3D11_USAGE_IMMUTABLE);
int32_t maxSize = mCompositor->GetMaxTextureSize();
if (mSize.width <= maxSize && mSize.height <= maxSize) {
if ((mSize.width <= maxSize && mSize.height <= maxSize) ||
(mFlags & TEXTURE_DISALLOW_BIGIMAGE)) {
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = aSurface->GetData();
initData.SysMemPitch = aSurface->Stride();
mCompositor->GetDevice()->CreateTexture2D(&desc, &initData, byRef(mTexture));
mIsTiled = false;
if (!mTexture) {
Reset();
return false;
}
} else {
mIsTiled = true;
uint32_t tileCount = GetRequiredTilesD3D11(mSize.width, maxSize) *
GetRequiredTilesD3D11(mSize.height, maxSize);
mTileTextures.resize(tileCount);
mTexture = nullptr;
for (uint32_t i = 0; i < tileCount; i++) {
IntRect tileRect = GetTileRect(i);
@ -251,11 +349,32 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface,
initData.SysMemPitch = aSurface->Stride();
mCompositor->GetDevice()->CreateTexture2D(&desc, &initData, byRef(mTileTextures[i]));
if (!mTileTextures[i]) {
Reset();
return false;
}
}
}
return true;
}
ID3D11Texture2D*
DataTextureSourceD3D11::GetD3D11Texture() const
{
return mIterating ? mTileTextures[mCurrentTile]
: mTexture;
}
void
DataTextureSourceD3D11::Reset()
{
mTexture = nullptr;
mTileTextures.resize(0);
mIsTiled = false;
mSize.width = 0;
mSize.height = 0;
}
IntRect
DataTextureSourceD3D11::GetTileRect(uint32_t aIndex) const
{
@ -274,8 +393,7 @@ DataTextureSourceD3D11::SetCompositor(Compositor* aCompositor)
{
CompositorD3D11* d3dCompositor = static_cast<CompositorD3D11*>(aCompositor);
if (mCompositor != d3dCompositor) {
mTexture = nullptr;
mTileTextures.resize(0);
Reset();
}
mCompositor = d3dCompositor;
}
@ -296,7 +414,7 @@ CreateDeprecatedTextureHostD3D11(SurfaceDescriptorType aDescriptorType,
result->SetFlags(aTextureFlags);
return result.forget();
return result;
}
@ -387,7 +505,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
}
mDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle,
aType == GFX_CONTENT_COLOR_ALPHA);
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aType));
mContentType = aType;
return true;
@ -677,7 +795,7 @@ DeprecatedTextureHostDXGID3D11::UpdateImpl(const SurfaceDescriptor& aImage,
return;
}
mFormat = aImage.get_SurfaceDescriptorD3D10().hasAlpha() ? FORMAT_B8G8R8A8 : FORMAT_B8G8R8X8;
mFormat = aImage.get_SurfaceDescriptorD3D10().format();
D3D11_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
@ -786,11 +904,11 @@ DeprecatedTextureHostYCbCrD3D11::UpdateImpl(const SurfaceDescriptor& aImage,
yuvDeserializer.GetCbCrStride(),
yuvDeserializer.GetCbCrSize(),
FORMAT_A8);
// We don't support partial updates for Y U V textures
// We don't support partial updates for YCbCr textures
NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
if (!srcY->Update(wrapperY, TEXTURE_FLAGS_DEFAULT) ||
!srcCb->Update(wrapperCb, TEXTURE_FLAGS_DEFAULT) ||
!srcCr->Update(wrapperCr, TEXTURE_FLAGS_DEFAULT)) {
if (!srcY->Update(wrapperY) ||
!srcCb->Update(wrapperCb) ||
!srcCr->Update(wrapperCr)) {
NS_WARNING("failed to update the DataTextureSource");
mFirstSource = nullptr;
mSize.width = 0;

Просмотреть файл

@ -25,18 +25,44 @@ class CompositorD3D11;
* A TextureClient to share a D3D10 texture with the compositor thread.
* The corresponding TextureHost is DXGITextureHostD3D11
*/
class TextureClientD3D11 : public TextureClient
class TextureClientD3D11 : public TextureClient,
public TextureClientDrawTarget
{
public:
virtual bool IsAllocated() const MOZ_OVERRIDE;
TextureClientD3D11(gfx::SurfaceFormat aFormat, TextureFlags aFlags);
virtual ~TextureClientD3D11();
// TextureClient
virtual bool IsAllocated() const MOZ_OVERRIDE { return !!mTexture; }
virtual bool Lock(OpenMode aOpenMode) MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
virtual TextureClientData* DropTextureData() MOZ_OVERRIDE { return nullptr; }
// TextureClientDrawTarget
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
virtual TextureClientDrawTarget* AsTextureClientDrawTarget() MOZ_OVERRIDE { return this; }
virtual TemporaryRef<gfx::DrawTarget> GetAsDrawTarget() MOZ_OVERRIDE;
virtual bool AllocateForSurface(gfx::IntSize aSize,
TextureAllocationFlags aFlags = ALLOC_DEFAULT) MOZ_OVERRIDE;
protected:
gfx::IntSize mSize;
RefPtr<ID3D10Texture2D> mTexture;
RefPtr<gfx::DrawTarget> mDrawTarget;
gfx::SurfaceFormat mFormat;
bool mIsLocked;
};
@ -71,17 +97,15 @@ class DataTextureSourceD3D11 : public DataTextureSource
public:
DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor);
DataTextureSourceD3D11(ID3D11Texture2D* aTexture,
gfx::SurfaceFormat aFormat);
DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor,
ID3D11Texture2D* aTexture);
virtual ~DataTextureSourceD3D11();
void SetCompositor(Compositor* aCompositor);
// DataTextureSource
virtual bool Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion = nullptr,
gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE;
@ -89,6 +113,8 @@ public:
virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
virtual ID3D11Texture2D* GetD3D11Texture() const MOZ_OVERRIDE;
virtual DataTextureSource* AsDataTextureSource() MOZ_OVERRIDE { return this; }
virtual void DeallocateDeviceData() MOZ_OVERRIDE { mTexture = nullptr; }
@ -97,6 +123,8 @@ public:
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
// TileIterator
virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return mIsTiled ? this : nullptr; }
@ -118,6 +146,8 @@ public:
protected:
gfx::IntRect GetTileRect(uint32_t aIndex) const;
void Reset();
std::vector< RefPtr<ID3D11Texture2D> > mTileTextures;
RefPtr<CompositorD3D11> mCompositor;
gfx::SurfaceFormat mFormat;
@ -157,8 +187,10 @@ public:
}
protected:
ID3D11Device* GetDevice();
RefPtr<DataTextureSourceD3D11> mTextureSource;
RefPtr<ID3D11Device> mDevice;
RefPtr<CompositorD3D11> mCompositor;
gfx::IntSize mSize;
WindowsHandle mHandle;
gfx::SurfaceFormat mFormat;

Просмотреть файл

@ -333,10 +333,23 @@ CompositorD3D9::DrawQuad(const gfx::Rect &aRect,
const int Y = 0, Cb = 1, Cr = 2;
TextureSource* source = ycbcrEffect->mTexture;
if (!source) {
NS_WARNING("No texture to composite");
return;
}
if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) {
// This can happen if we failed to upload the textures, most likely
// because of unsupported dimensions (we don't tile YCbCr textures).
return;
}
TextureSourceD3D9* sourceY = source->GetSubSource(Y)->AsSourceD3D9();
TextureSourceD3D9* sourceCb = source->GetSubSource(Cb)->AsSourceD3D9();
TextureSourceD3D9* sourceCr = source->GetSubSource(Cr)->AsSourceD3D9();
MOZ_ASSERT(sourceY->GetD3D9Texture());
MOZ_ASSERT(sourceCb->GetD3D9Texture());
MOZ_ASSERT(sourceCr->GetD3D9Texture());

Просмотреть файл

@ -36,7 +36,7 @@ CreateDeprecatedTextureHostD3D9(SurfaceDescriptorType aDescriptorType,
}
result->SetFlags(aTextureFlags);
return result.forget();
return result;
}
TextureSourceD3D9::~TextureSourceD3D9()
@ -264,7 +264,7 @@ TextureSourceD3D9::DataToTexture(DeviceManagerD3D9* aDeviceManager,
FinishTextures(aDeviceManager, texture, surface);
return texture.forget();
return texture;
}
void
@ -415,21 +415,24 @@ DeprecatedTextureHostYCbCrD3D9::UpdateImpl(const SurfaceDescriptor& aImage,
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
RefPtr<DataTextureSource> srcY;
RefPtr<DataTextureSource> srcU;
RefPtr<DataTextureSource> srcV;
RefPtr<DataTextureSource> srcCb;
RefPtr<DataTextureSource> srcCr;
if (!mFirstSource) {
srcY = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, false, mStereoMode);
srcU = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, false, mStereoMode);
srcV = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, false, mStereoMode);
srcY = new DataTextureSourceD3D9(FORMAT_A8, mCompositor,
TEXTURE_DISALLOW_BIGIMAGE, mStereoMode);
srcCb = new DataTextureSourceD3D9(FORMAT_A8, mCompositor,
TEXTURE_DISALLOW_BIGIMAGE, mStereoMode);
srcCr = new DataTextureSourceD3D9(FORMAT_A8, mCompositor,
TEXTURE_DISALLOW_BIGIMAGE, mStereoMode);
mFirstSource = srcY;
srcY->SetNextSibling(srcU);
srcU->SetNextSibling(srcV);
srcY->SetNextSibling(srcCb);
srcCb->SetNextSibling(srcCr);
} else {
MOZ_ASSERT(mFirstSource->GetNextSibling());
MOZ_ASSERT(mFirstSource->GetNextSibling()->GetNextSibling());
srcY = mFirstSource;
srcU = mFirstSource->GetNextSibling()->AsDataTextureSource();
srcV = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource();
srcCb = mFirstSource->GetNextSibling()->AsDataTextureSource();
srcCr = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource();
}
RefPtr<DataSourceSurface> wrapperY =
@ -447,11 +450,11 @@ DeprecatedTextureHostYCbCrD3D9::UpdateImpl(const SurfaceDescriptor& aImage,
yuvDeserializer.GetCbCrStride(),
yuvDeserializer.GetCbCrSize(),
FORMAT_A8);
// We don't support partial updates for Y U V textures
// We don't support partial updates for YCbCr textures
NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
if (!srcY->Update(wrapperY, TEXTURE_FLAGS_DEFAULT) ||
!srcU->Update(wrapperCb, TEXTURE_FLAGS_DEFAULT) ||
!srcV->Update(wrapperCr, TEXTURE_FLAGS_DEFAULT)) {
if (!srcY->Update(wrapperY) ||
!srcCb->Update(wrapperCb) ||
!srcCr->Update(wrapperCr)) {
NS_WARNING("failed to update the DataTextureSource");
mSize.width = 0;
mSize.height = 0;
@ -481,7 +484,7 @@ TextureSourceD3D9::TextureToTexture(DeviceManagerD3D9* aDeviceManager,
return nullptr;
}
return texture.forget();
return texture;
}
void
@ -605,7 +608,7 @@ TextureSourceD3D9::SurfaceToTexture(DeviceManagerD3D9* aDeviceManager,
FinishTextures(aDeviceManager, texture, surface);
return texture.forget();
return texture;
}
void
@ -952,12 +955,12 @@ DeprecatedTextureClientDIB::SetDescriptor(const SurfaceDescriptor& aDescriptor)
DataTextureSourceD3D9::DataTextureSourceD3D9(gfx::SurfaceFormat aFormat,
CompositorD3D9* aCompositor,
bool aDisallowBigImage,
TextureFlags aFlags,
StereoMode aStereoMode)
: mFormat(aFormat)
, mCompositor(aCompositor)
, mCurrentTile(0)
, mDisallowBigImage(aDisallowBigImage)
, mFlags(aFlags)
, mIsTiled(false)
, mIterating(false)
{
@ -970,9 +973,15 @@ DataTextureSourceD3D9::~DataTextureSourceD3D9()
MOZ_COUNT_DTOR(DataTextureSourceD3D9);
}
IDirect3DTexture9*
DataTextureSourceD3D9::GetD3D9Texture()
{
return mIterating ? mTileTextures[mCurrentTile]
: mTexture;
}
bool
DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion,
gfx::IntPoint* aSrcOffset)
{
@ -982,6 +991,7 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
MOZ_ASSERT(!aDestRegion && !aSrcOffset);
if (!mCompositor || !mCompositor->device()) {
NS_WARNING("No D3D device to update the texture.");
return false;
}
mSize = aSurface->GetSize();
@ -1010,7 +1020,8 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
int32_t maxSize = mCompositor->GetMaxTextureSize();
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
if (mSize.width <= maxSize && mSize.height <= maxSize) {
if ((mSize.width <= maxSize && mSize.height <= maxSize) ||
(mFlags & TEXTURE_DISALLOW_BIGIMAGE)) {
mTexture = DataToTexture(deviceManager,
aSurface->GetData(), aSurface->Stride(),
ThebesIntSize(mSize), format, bpp);
@ -1025,6 +1036,7 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
uint32_t tileCount = GetRequiredTilesD3D9(mSize.width, maxSize) *
GetRequiredTilesD3D9(mSize.height, maxSize);
mTileTextures.resize(tileCount);
mTexture = nullptr;
for (uint32_t i = 0; i < tileCount; i++) {
IntRect tileRect = GetTileRect(i);
@ -1048,6 +1060,17 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
return true;
}
void
DataTextureSourceD3D9::SetCompositor(Compositor* aCompositor)
{
CompositorD3D9* d3dCompositor = static_cast<CompositorD3D9*>(aCompositor);
if (d3dCompositor != mCompositor) {
Reset();
mCompositor = d3dCompositor;
}
}
void
DataTextureSourceD3D9::Reset()
{
@ -1055,6 +1078,7 @@ DataTextureSourceD3D9::Reset()
mSize.height = 0;
mIsTiled = false;
mTexture = nullptr;
mTileTextures.clear();
}
IntRect

Просмотреть файл

@ -100,7 +100,7 @@ class DataTextureSourceD3D9 : public DataTextureSource
public:
DataTextureSourceD3D9(gfx::SurfaceFormat aFormat,
CompositorD3D9* aCompositor,
bool aAllowBigImage = true,
TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT,
StereoMode aStereoMode = STEREO_MODE_MONO);
virtual ~DataTextureSourceD3D9();
@ -108,7 +108,6 @@ public:
// DataTextureSource
virtual bool Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion = nullptr,
gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE;
@ -116,6 +115,8 @@ public:
virtual TextureSourceD3D9* AsSourceD3D9() MOZ_OVERRIDE { return this; }
virtual IDirect3DTexture9* GetD3D9Texture() MOZ_OVERRIDE;
virtual DataTextureSource* AsDataTextureSource() MOZ_OVERRIDE { return this; }
virtual void DeallocateDeviceData() MOZ_OVERRIDE { mTexture = nullptr; }
@ -124,6 +125,8 @@ public:
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
// TileIterator
virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return mIsTiled ? this : nullptr; }
@ -151,7 +154,7 @@ protected:
RefPtr<CompositorD3D9> mCompositor;
gfx::SurfaceFormat mFormat;
uint32_t mCurrentTile;
bool mDisallowBigImage;
TextureFlags mFlags;
bool mIsTiled;
bool mIterating;
};

Просмотреть файл

@ -39,7 +39,7 @@ struct SurfaceDescriptorDIB {
struct SurfaceDescriptorD3D10 {
WindowsHandle handle;
bool hasAlpha;
SurfaceFormat format;
};
struct SurfaceDescriptorMacIOSurface {

Просмотреть файл

@ -1555,8 +1555,7 @@ TemporaryRef<DataTextureSource>
CompositorOGL::CreateDataTextureSource(TextureFlags aFlags)
{
RefPtr<DataTextureSource> result =
new TextureImageTextureSourceOGL(mGLContext,
!(aFlags & TEXTURE_DISALLOW_BIGIMAGE));
new TextureImageTextureSourceOGL(mGLContext, aFlags);
return result;
}

Просмотреть файл

@ -171,11 +171,13 @@ GrallocTextureClientOGL::Lock(OpenMode aMode)
NS_WARNING("Couldn't lock graphic buffer");
return false;
}
return true;
return BufferTextureClient::Lock(aMode);
}
void
GrallocTextureClientOGL::Unlock()
{
BufferTextureClient::Unlock();
mMappedBuffer = nullptr;
mGraphicBuffer->unlock();
}

Просмотреть файл

@ -225,7 +225,6 @@ CompositableDataGonkOGL::DeleteTextureIfPresent()
bool
TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion,
gfx::IntPoint* aSrcOffset)
{
@ -240,7 +239,13 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
if (!mTexImage ||
mTexImage->GetSize() != size ||
mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) {
if (mAllowBigImage) {
if (mFlags & TEXTURE_DISALLOW_BIGIMAGE) {
mTexImage = CreateBasicTextureImage(mGL, size,
gfx::ContentForFormat(aSurface->GetFormat()),
WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT),
FlagsToGLFlags(mFlags),
SurfaceFormatToImageFormat(aSurface->GetFormat()));
} else {
// XXX - clarify which size we want to use. IncrementalContentHost will
// require the size of the destination surface to be different from
// the size of aSurface.
@ -248,16 +253,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
mTexImage = CreateTextureImage(mGL,
size,
gfx::ContentForFormat(aSurface->GetFormat()),
WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT),
FlagsToGLFlags(aFlags),
SurfaceFormatToImageFormat(aSurface->GetFormat()));
} else {
mTexImage = CreateBasicTextureImage(mGL,
size,
gfx::ContentForFormat(aSurface->GetFormat()),
WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT),
FlagsToGLFlags(aFlags),
SurfaceFormatToImageFormat(aSurface->GetFormat()));
}
}
@ -269,6 +265,17 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
return true;
}
void
TextureImageTextureSourceOGL::SetCompositor(Compositor* aCompositor)
{
CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
if (!glCompositor || (mGL != glCompositor->gl())) {
DeallocateDeviceData();
mGL = glCompositor ? glCompositor->gl() : nullptr;
}
}
gfx::IntSize
TextureImageTextureSourceOGL::GetSize() const
{

Просмотреть файл

@ -154,16 +154,16 @@ class TextureImageTextureSourceOGL : public DataTextureSource
, public TileIterator
{
public:
TextureImageTextureSourceOGL(gl::GLContext* aGL, bool aAllowBiImage = true)
TextureImageTextureSourceOGL(gl::GLContext* aGL,
TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT)
: mGL(aGL)
, mAllowBigImage(aAllowBiImage)
, mFlags(aFlags)
, mIterating(false)
{}
// DataTextureSource
virtual bool Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion = nullptr,
gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE;
@ -185,6 +185,8 @@ public:
virtual bool IsValid() const MOZ_OVERRIDE { return !!mTexImage; }
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
virtual GLenum GetWrapMode() const MOZ_OVERRIDE
{
return mTexImage->GetWrapMode();
@ -220,7 +222,7 @@ public:
protected:
nsRefPtr<gl::TextureImage> mTexImage;
gl::GLContext* mGL;
bool mAllowBigImage;
TextureFlags mFlags;
bool mIterating;
};