mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 874721, bug 899435. D3D9 compositor and windows OMTC window resizing. r=Bas, mattwoodrow
This commit is contained in:
parent
102bdb9382
commit
dd58f82344
@ -2213,14 +2213,19 @@ TabChild::InitRenderingState()
|
||||
if (id != 0) {
|
||||
// Pushing layers transactions directly to a separate
|
||||
// compositor context.
|
||||
PCompositorChild* compositorChild = CompositorChild::Get();
|
||||
PCompositorChild* compositorChild = CompositorChild::Get();
|
||||
if (!compositorChild) {
|
||||
NS_WARNING("failed to get CompositorChild instance");
|
||||
return false;
|
||||
}
|
||||
bool success;
|
||||
shadowManager =
|
||||
compositorChild->SendPLayerTransactionConstructor(mTextureFactoryIdentifier.mParentBackend,
|
||||
id, &mTextureFactoryIdentifier);
|
||||
id, &mTextureFactoryIdentifier, &success);
|
||||
if (!success) {
|
||||
NS_WARNING("failed to properly allocate layer transaction");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Pushing transactions to the parent content.
|
||||
shadowManager = remoteFrame->SendPLayerTransactionConstructor();
|
||||
|
@ -7,6 +7,8 @@
|
||||
#define MOZILLA_LAYERS_COMPOSITORTYPES_H
|
||||
|
||||
#include "LayersTypes.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -123,7 +125,8 @@ enum DeprecatedTextureClientType
|
||||
TEXTURE_SHARED_GL_EXTERNAL, // GLContext::SharedTextureHandle, the ownership of
|
||||
// the SurfaceDescriptor passed to the texture
|
||||
// remains with whoever passed it.
|
||||
TEXTURE_STREAM_GL // WebGL streaming buffer
|
||||
TEXTURE_STREAM_GL, // WebGL streaming buffer
|
||||
TEXTURE_FALLBACK // A fallback path appropriate for the platform
|
||||
};
|
||||
|
||||
/**
|
||||
@ -166,15 +169,18 @@ enum DeprecatedTextureHostFlags
|
||||
struct TextureFactoryIdentifier
|
||||
{
|
||||
LayersBackend mParentBackend;
|
||||
GeckoProcessType mParentProcessId;
|
||||
int32_t mMaxTextureSize;
|
||||
bool mSupportsTextureBlitting;
|
||||
bool mSupportsPartialUploads;
|
||||
|
||||
TextureFactoryIdentifier(LayersBackend aLayersBackend = LAYERS_NONE,
|
||||
GeckoProcessType aParentProcessId = GeckoProcessType_Default,
|
||||
int32_t aMaxTextureSize = 0,
|
||||
bool aSupportsTextureBlitting = false,
|
||||
bool aSupportsPartialUploads = false)
|
||||
: mParentBackend(aLayersBackend)
|
||||
, mParentProcessId(aParentProcessId)
|
||||
, mMaxTextureSize(aMaxTextureSize)
|
||||
, mSupportsTextureBlitting(aSupportsTextureBlitting)
|
||||
, mSupportsPartialUploads(aSupportsPartialUploads)
|
||||
|
@ -446,7 +446,8 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
PaintState result;
|
||||
// We need to disable rotation if we're going to be resampled when
|
||||
// drawing, because we might sample across the rotation boundary.
|
||||
bool canHaveRotation = !(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
|
||||
bool canHaveRotation = gfxPlatform::BufferRotationEnabled() &&
|
||||
!(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
|
||||
|
||||
nsIntRegion validRegion = aLayer->GetValidRegion();
|
||||
|
||||
|
@ -40,6 +40,7 @@ struct YCbCrBufferInfo
|
||||
uint32_t mYHeight;
|
||||
uint32_t mCbCrWidth;
|
||||
uint32_t mCbCrHeight;
|
||||
StereoMode mStereoMode;
|
||||
};
|
||||
|
||||
static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData)
|
||||
@ -103,6 +104,12 @@ gfxIntSize YCbCrImageDataDeserializerBase::GetCbCrSize()
|
||||
return gfxIntSize(info->mCbCrWidth, info->mCbCrHeight);
|
||||
}
|
||||
|
||||
StereoMode YCbCrImageDataDeserializerBase::GetStereoMode()
|
||||
{
|
||||
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
|
||||
return info->mStereoMode;
|
||||
}
|
||||
|
||||
// Offset in bytes
|
||||
static size_t ComputeOffset(uint32_t aHeight, uint32_t aStride)
|
||||
{
|
||||
@ -144,7 +151,8 @@ YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize)
|
||||
|
||||
void
|
||||
YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
const gfx::IntSize& aCbCrSize)
|
||||
const gfx::IntSize& aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
|
||||
info->mYOffset = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
|
||||
@ -157,14 +165,17 @@ YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
info->mYHeight = aYSize.height;
|
||||
info->mCbCrWidth = aCbCrSize.width;
|
||||
info->mCbCrHeight = aCbCrSize.height;
|
||||
info->mStereoMode = aStereoMode;
|
||||
}
|
||||
|
||||
void
|
||||
YCbCrImageDataSerializer::InitializeBufferInfo(const gfxIntSize& aYSize,
|
||||
const gfxIntSize& aCbCrSize)
|
||||
const gfxIntSize& aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
InitializeBufferInfo(gfx::IntSize(aYSize.width, aYSize.height),
|
||||
gfx::IntSize(aCbCrSize.width, aCbCrSize.height));
|
||||
gfx::IntSize(aCbCrSize.width, aCbCrSize.height),
|
||||
aStereoMode);
|
||||
}
|
||||
|
||||
static void CopyLineWithSkip(const uint8_t* src, uint8_t* dst, uint32_t len, uint32_t skip) {
|
||||
|
@ -66,6 +66,11 @@ public:
|
||||
*/
|
||||
gfxIntSize GetCbCrSize();
|
||||
|
||||
/**
|
||||
* Stereo mode for the image.
|
||||
*/
|
||||
StereoMode GetStereoMode();
|
||||
|
||||
/**
|
||||
* Return a pointer to the begining of the data buffer.
|
||||
*/
|
||||
@ -111,9 +116,11 @@ public:
|
||||
* buffer on which we want to store the image.
|
||||
*/
|
||||
void InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
const gfx::IntSize& aCbCrSize);
|
||||
const gfx::IntSize& aCbCrSize,
|
||||
StereoMode aStereoMode);
|
||||
void InitializeBufferInfo(const gfxIntSize& aYSize,
|
||||
const gfxIntSize& aCbCrSize);
|
||||
const gfxIntSize& aCbCrSize,
|
||||
StereoMode aStereoMode);
|
||||
|
||||
bool CopyData(const uint8_t* aYData,
|
||||
const uint8_t* aCbData, const uint8_t* aCrData,
|
||||
|
@ -43,7 +43,9 @@ public:
|
||||
|
||||
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
|
||||
{
|
||||
return TextureFactoryIdentifier(LAYERS_BASIC, GetMaxTextureSize());
|
||||
return TextureFactoryIdentifier(LAYERS_BASIC,
|
||||
XRE_GetProcessType(),
|
||||
GetMaxTextureSize());
|
||||
}
|
||||
|
||||
virtual TemporaryRef<CompositingRenderTarget>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "gfxPlatform.h"
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/layers/TextureD3D9.h"
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
@ -112,6 +113,7 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
|
||||
break;
|
||||
case TEXTURE_YCBCR:
|
||||
if (parentBackend == LAYERS_OPENGL ||
|
||||
parentBackend == LAYERS_D3D9 ||
|
||||
parentBackend == LAYERS_D3D11 ||
|
||||
parentBackend == LAYERS_BASIC) {
|
||||
result = new DeprecatedTextureClientShmemYCbCr(GetForwarder(), GetTextureInfo());
|
||||
@ -123,11 +125,23 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
|
||||
result = new DeprecatedTextureClientD3D11(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
}
|
||||
if (parentBackend == LAYERS_D3D9 &&
|
||||
!GetForwarder()->ForwardsToDifferentProcess()) {
|
||||
result = new DeprecatedTextureClientD3D9(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// fall through to TEXTURE_SHMEM
|
||||
case TEXTURE_SHMEM:
|
||||
result = new DeprecatedTextureClientShmem(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
case TEXTURE_FALLBACK:
|
||||
#ifdef XP_WIN
|
||||
if (parentBackend == LAYERS_D3D9) {
|
||||
result = new DeprecatedTextureClientShmem(GetForwarder(), GetTextureInfo());
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "Unhandled texture client type");
|
||||
}
|
||||
|
@ -26,9 +26,10 @@ ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
|
||||
{
|
||||
LayersBackend backend = aForwarder->GetCompositorBackendType();
|
||||
if (backend != LAYERS_OPENGL &&
|
||||
backend != LAYERS_D3D9 &&
|
||||
backend != LAYERS_D3D11 &&
|
||||
backend != LAYERS_BASIC) {
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool useDoubleBuffering = false;
|
||||
@ -138,6 +139,25 @@ ContentClientRemoteBuffer::EndPaint()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ContentClientRemoteBuffer::CreateAndAllocateDeprecatedTextureClient(RefPtr<DeprecatedTextureClient>& aClient)
|
||||
{
|
||||
aClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(aClient, "Failed to create texture client");
|
||||
|
||||
if (!aClient->EnsureAllocated(mSize, mContentType)) {
|
||||
aClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK);
|
||||
MOZ_ASSERT(aClient, "Failed to create texture client");
|
||||
if (!aClient->EnsureAllocated(mSize, mContentType)) {
|
||||
NS_WARNING("Could not allocate texture client");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(*aClient->GetDescriptor()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType,
|
||||
const nsIntRect& aRect,
|
||||
@ -155,22 +175,20 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType,
|
||||
}
|
||||
DestroyBuffers();
|
||||
}
|
||||
mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
|
||||
mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client");
|
||||
if (aFlags & BUFFER_COMPONENT_ALPHA) {
|
||||
mDeprecatedTextureClientOnWhite = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mDeprecatedTextureClientOnWhite, "Failed to create texture client");
|
||||
mTextureInfo.mTextureFlags |= ComponentAlpha;
|
||||
}
|
||||
|
||||
mContentType = aType;
|
||||
mSize = gfx::IntSize(aRect.width, aRect.height);
|
||||
mDeprecatedTextureClient->EnsureAllocated(mSize, mContentType);
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(*mDeprecatedTextureClient->GetDescriptor()));
|
||||
if (mDeprecatedTextureClientOnWhite) {
|
||||
mDeprecatedTextureClientOnWhite->EnsureAllocated(mSize, mContentType);
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(*mDeprecatedTextureClientOnWhite->GetDescriptor()));
|
||||
mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
|
||||
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClient)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aFlags & BUFFER_COMPONENT_ALPHA) {
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClientOnWhite)) {
|
||||
return;
|
||||
}
|
||||
mTextureInfo.mTextureFlags |= ComponentAlpha;
|
||||
}
|
||||
|
||||
CreateFrontBufferAndNotify(aRect);
|
||||
@ -283,18 +301,18 @@ ContentClientDoubleBuffered::~ContentClientDoubleBuffered()
|
||||
void
|
||||
ContentClientDoubleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBufferRect)
|
||||
{
|
||||
mFrontClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mFrontClient, "Failed to create texture client");
|
||||
mFrontClient->EnsureAllocated(mSize, mContentType);
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mFrontClient)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mTextureInfo.mTextureFlags & ComponentAlpha) {
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mFrontClientOnWhite)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mFrontBufferRect = aBufferRect;
|
||||
mFrontBufferRotation = nsIntPoint();
|
||||
|
||||
if (mTextureInfo.mTextureFlags & ComponentAlpha) {
|
||||
mFrontClientOnWhite = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mFrontClientOnWhite, "Failed to create texture client");
|
||||
mFrontClientOnWhite->EnsureAllocated(mSize, mContentType);
|
||||
}
|
||||
|
||||
mForwarder->CreatedDoubleBuffer(this,
|
||||
*mFrontClient->GetDescriptor(),
|
||||
|
@ -253,6 +253,8 @@ protected:
|
||||
// lock it now.
|
||||
virtual void LockFrontBuffer() {}
|
||||
|
||||
bool CreateAndAllocateDeprecatedTextureClient(RefPtr<DeprecatedTextureClient>& aClient);
|
||||
|
||||
RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
|
||||
RefPtr<DeprecatedTextureClient> mDeprecatedTextureClientOnWhite;
|
||||
// keep a record of texture clients we have created and need to keep
|
||||
|
@ -121,7 +121,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
||||
mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV);
|
||||
gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
|
||||
gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
|
||||
if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize)) {
|
||||
if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize, data->mStereoMode)) {
|
||||
mFrontBuffer = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
@ -240,7 +240,9 @@ BufferTextureClient::UpdateYCbCr(const PlanarYCbCrImage::Data& aData)
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize)
|
||||
BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize,
|
||||
aCbCrSize);
|
||||
@ -249,7 +251,8 @@ BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSiz
|
||||
}
|
||||
YCbCrImageDataSerializer serializer(GetBuffer());
|
||||
serializer.InitializeBufferInfo(aYSize,
|
||||
aCbCrSize);
|
||||
aCbCrSize,
|
||||
aStereoMode);
|
||||
mSize = aYSize;
|
||||
return true;
|
||||
}
|
||||
@ -304,7 +307,7 @@ DeprecatedTextureClientShmem::ReleaseResources()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientShmem::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aContentType)
|
||||
{
|
||||
@ -321,6 +324,7 @@ DeprecatedTextureClientShmem::EnsureAllocated(gfx::IntSize aSize,
|
||||
NS_WARNING("creating SurfaceDescriptor failed!");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -432,11 +436,12 @@ DeprecatedTextureClientShmemYCbCr::SetDescriptorFromReply(const SurfaceDescripto
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientShmemYCbCr::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType)
|
||||
{
|
||||
NS_RUNTIMEABORT("not enough arguments to do this (need both Y and CbCr sizes)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -448,7 +453,7 @@ DeprecatedTextureClientTile::DeprecatedTextureClientTile(CompositableForwarder*
|
||||
mTextureInfo.mDeprecatedTextureHostFlags = TEXTURE_HOST_TILED;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientTile::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType)
|
||||
{
|
||||
if (!mSurface ||
|
||||
@ -459,6 +464,7 @@ DeprecatedTextureClientTile::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gf
|
||||
mSurface = new gfxReusableSurfaceWrapper(tmpTile);
|
||||
mContentType = aType;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxImageSurface*
|
||||
@ -580,7 +586,8 @@ bool AutoLockYCbCrClient::EnsureDeprecatedTextureClient(PlanarYCbCrImage* aImage
|
||||
|
||||
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
|
||||
serializer.InitializeBufferInfo(data->mYSize,
|
||||
data->mCbCrSize);
|
||||
data->mCbCrSize,
|
||||
data->mStereoMode);
|
||||
|
||||
*mDescriptor = YCbCrImage(shmem, 0);
|
||||
|
||||
|
@ -55,7 +55,9 @@ class TextureClientYCbCr
|
||||
{
|
||||
public:
|
||||
virtual bool UpdateYCbCr(const PlanarYCbCrImage::Data& aData) = 0;
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize) = 0;
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode) = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -203,7 +205,9 @@ public:
|
||||
|
||||
virtual bool UpdateYCbCr(const PlanarYCbCrImage::Data& aData) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize) MOZ_OVERRIDE;
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode) MOZ_OVERRIDE;
|
||||
|
||||
gfx::SurfaceFormat GetFormat() const { return mFormat; }
|
||||
|
||||
@ -354,8 +358,9 @@ public:
|
||||
/**
|
||||
* Ensure that the texture client is suitable for the given size and content
|
||||
* type and that any initialisation has taken place.
|
||||
* Returns true if succeeded, false if failed.
|
||||
*/
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize,
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType) = 0;
|
||||
|
||||
/**
|
||||
@ -422,13 +427,13 @@ public:
|
||||
|
||||
virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE
|
||||
{
|
||||
return aType == TEXTURE_SHMEM || aType == TEXTURE_CONTENT;
|
||||
return aType == TEXTURE_SHMEM || aType == TEXTURE_CONTENT || aType == TEXTURE_FALLBACK;
|
||||
}
|
||||
virtual gfxImageSurface* LockImageSurface() MOZ_OVERRIDE;
|
||||
virtual gfxASurface* LockSurface() MOZ_OVERRIDE { return GetSurface(); }
|
||||
virtual gfx::DrawTarget* LockDrawTarget();
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ReleaseResources() MOZ_OVERRIDE;
|
||||
virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
@ -456,7 +461,7 @@ public:
|
||||
~DeprecatedTextureClientShmemYCbCr() { ReleaseResources(); }
|
||||
|
||||
virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE { return aType == TEXTURE_YCBCR; }
|
||||
void EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
bool EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
virtual void SetDescriptorFromReply(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
virtual void ReleaseResources();
|
||||
@ -471,7 +476,7 @@ public:
|
||||
const TextureInfo& aTextureInfo);
|
||||
~DeprecatedTextureClientTile();
|
||||
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize,
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual gfxImageSurface* LockImageSurface() MOZ_OVERRIDE;
|
||||
|
@ -33,7 +33,8 @@ CanvasLayerComposite::~CanvasLayerComposite()
|
||||
CleanupResources();
|
||||
}
|
||||
|
||||
void CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost) {
|
||||
void
|
||||
CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost) {
|
||||
mImageHost = aHost;
|
||||
}
|
||||
|
||||
@ -46,7 +47,7 @@ CanvasLayerComposite::GetLayer()
|
||||
LayerRenderState
|
||||
CanvasLayerComposite::GetRenderState()
|
||||
{
|
||||
if (mDestroyed || !mImageHost) {
|
||||
if (mDestroyed || !mImageHost || !mImageHost->IsAttached()) {
|
||||
return LayerRenderState();
|
||||
}
|
||||
return mImageHost->GetRenderState();
|
||||
@ -56,7 +57,7 @@ void
|
||||
CanvasLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
const nsIntRect& aClipRect)
|
||||
{
|
||||
if (!mImageHost) {
|
||||
if (!mImageHost || !mImageHost->IsAttached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,8 +99,13 @@ CanvasLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
}
|
||||
|
||||
CompositableHost*
|
||||
CanvasLayerComposite::GetCompositableHost() {
|
||||
return mImageHost.get();
|
||||
CanvasLayerComposite::GetCompositableHost()
|
||||
{
|
||||
if (mImageHost->IsAttached()) {
|
||||
return mImageHost.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -117,7 +123,7 @@ CanvasLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||
{
|
||||
CanvasLayer::PrintInfo(aTo, aPrefix);
|
||||
aTo += "\n";
|
||||
if (mImageHost) {
|
||||
if (mImageHost && mImageHost->IsAttached()) {
|
||||
nsAutoCString pfx(aPrefix);
|
||||
pfx += " ";
|
||||
mImageHost->PrintInfo(aTo, pfx.get());
|
||||
|
@ -18,6 +18,7 @@ CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
|
||||
: mTextureInfo(aTextureInfo)
|
||||
, mCompositor(nullptr)
|
||||
, mLayer(nullptr)
|
||||
, mAttached(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CompositableHost);
|
||||
}
|
||||
|
@ -187,13 +187,18 @@ public:
|
||||
virtual void Attach(Layer* aLayer, Compositor* aCompositor)
|
||||
{
|
||||
MOZ_ASSERT(aCompositor, "Compositor is required");
|
||||
MOZ_ASSERT(!IsAttached());
|
||||
SetCompositor(aCompositor);
|
||||
SetLayer(aLayer);
|
||||
mAttached = true;
|
||||
}
|
||||
void Detach() {
|
||||
void Detach()
|
||||
{
|
||||
SetLayer(nullptr);
|
||||
SetCompositor(nullptr);
|
||||
mAttached = false;
|
||||
}
|
||||
bool IsAttached() { return mAttached; }
|
||||
|
||||
virtual void Dump(FILE* aFile=nullptr,
|
||||
const char* aPrefix="",
|
||||
@ -219,6 +224,7 @@ protected:
|
||||
Compositor* mCompositor;
|
||||
Layer* mLayer;
|
||||
RefPtr<TextureHost> mFirstTexture;
|
||||
bool mAttached;
|
||||
};
|
||||
|
||||
class CompositableParentManager;
|
||||
|
@ -54,7 +54,7 @@ ImageLayerComposite::Disconnect()
|
||||
LayerRenderState
|
||||
ImageLayerComposite::GetRenderState()
|
||||
{
|
||||
if (mImageHost) {
|
||||
if (mImageHost && mImageHost->IsAttached()) {
|
||||
return mImageHost->GetRenderState();
|
||||
}
|
||||
return LayerRenderState();
|
||||
@ -70,7 +70,7 @@ void
|
||||
ImageLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
const nsIntRect& aClipRect)
|
||||
{
|
||||
if (!mImageHost) {
|
||||
if (!mImageHost || !mImageHost->IsAttached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -108,7 +108,8 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
|
||||
// Snap image edges to pixel boundaries
|
||||
gfxRect sourceRect(0, 0, 0, 0);
|
||||
if (mImageHost &&
|
||||
(mImageHost->GetDeprecatedTextureHost() || mImageHost->GetTextureHost())) {
|
||||
mImageHost->IsAttached() &&
|
||||
(mImageHost->GetDeprecatedTextureHost() || mImageHost->GetTextureHost())) {
|
||||
IntSize size =
|
||||
mImageHost->GetTextureHost() ? mImageHost->GetTextureHost()->GetSize()
|
||||
: mImageHost->GetDeprecatedTextureHost()->GetSize();
|
||||
@ -132,8 +133,12 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
|
||||
}
|
||||
|
||||
CompositableHost*
|
||||
ImageLayerComposite::GetCompositableHost() {
|
||||
return mImageHost.get();
|
||||
ImageLayerComposite::GetCompositableHost()
|
||||
{
|
||||
if (mImageHost->IsAttached())
|
||||
return mImageHost.get();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -151,7 +156,7 @@ ImageLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||
{
|
||||
ImageLayer::PrintInfo(aTo, aPrefix);
|
||||
aTo += "\n";
|
||||
if (mImageHost) {
|
||||
if (mImageHost && mImageHost->IsAttached()) {
|
||||
nsAutoCString pfx(aPrefix);
|
||||
pfx += " ";
|
||||
mImageHost->PrintInfo(aTo, pfx.get());
|
||||
|
@ -86,6 +86,7 @@ LayerManagerComposite::ClearCachedResources(Layer* aSubtree)
|
||||
LayerManagerComposite::LayerManagerComposite(Compositor* aCompositor)
|
||||
: mCompositor(aCompositor)
|
||||
{
|
||||
MOZ_ASSERT(aCompositor);
|
||||
}
|
||||
|
||||
LayerManagerComposite::~LayerManagerComposite()
|
||||
|
@ -27,15 +27,11 @@ TemporaryRef<DeprecatedTextureHost> CreateBasicDeprecatedTextureHost(SurfaceDesc
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags);
|
||||
|
||||
#ifdef XP_WIN
|
||||
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostD3D9(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags)
|
||||
{
|
||||
NS_RUNTIMEABORT("not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t aTextureFlags);
|
||||
|
||||
#ifdef XP_WIN
|
||||
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostD3D11(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags);
|
||||
@ -51,11 +47,11 @@ DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptorType aDescri
|
||||
return CreateDeprecatedTextureHostOGL(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#ifdef XP_WIN
|
||||
case LAYERS_D3D9:
|
||||
return CreateDeprecatedTextureHostD3D9(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#ifdef XP_WIN
|
||||
case LAYERS_D3D11:
|
||||
return CreateDeprecatedTextureHostD3D11(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
|
@ -31,6 +31,7 @@ class Compositor;
|
||||
class SurfaceDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureSourceOGL;
|
||||
class TextureSourceD3D9;
|
||||
class TextureSourceD3D11;
|
||||
class TextureSourceBasic;
|
||||
class TextureParent;
|
||||
@ -87,18 +88,11 @@ public:
|
||||
virtual gfx::SurfaceFormat GetFormat() const { return gfx::FORMAT_UNKNOWN; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the OpenGL backend.
|
||||
* Cast to a TextureSource for for each backend..
|
||||
*/
|
||||
virtual TextureSourceOGL* AsSourceOGL() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the D3D11 backend.
|
||||
*/
|
||||
virtual TextureSourceD3D9* AsSourceD3D9() { return nullptr; }
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the software backend.
|
||||
*/
|
||||
virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
|
||||
|
||||
/**
|
||||
|
@ -29,6 +29,7 @@ ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager)
|
||||
: ThebesLayer(aManager, nullptr)
|
||||
, LayerComposite(aManager)
|
||||
, mBuffer(nullptr)
|
||||
, mRequiresTiledProperties(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ThebesLayerComposite);
|
||||
mImplData = static_cast<LayerComposite*>(this);
|
||||
@ -37,15 +38,13 @@ ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager)
|
||||
ThebesLayerComposite::~ThebesLayerComposite()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ThebesLayerComposite);
|
||||
if (mBuffer) {
|
||||
mBuffer->Detach();
|
||||
}
|
||||
CleanupResources();
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerComposite::SetCompositableHost(CompositableHost* aHost)
|
||||
{
|
||||
mBuffer= static_cast<ContentHost*>(aHost);
|
||||
mBuffer = static_cast<ContentHost*>(aHost);
|
||||
}
|
||||
|
||||
void
|
||||
@ -58,10 +57,7 @@ void
|
||||
ThebesLayerComposite::Destroy()
|
||||
{
|
||||
if (!mDestroyed) {
|
||||
if (mBuffer) {
|
||||
mBuffer->Detach();
|
||||
}
|
||||
mBuffer = nullptr;
|
||||
CleanupResources();
|
||||
mDestroyed = true;
|
||||
}
|
||||
}
|
||||
@ -75,13 +71,14 @@ ThebesLayerComposite::GetLayer()
|
||||
TiledLayerComposer*
|
||||
ThebesLayerComposite::GetTiledLayerComposer()
|
||||
{
|
||||
MOZ_ASSERT(mBuffer && mBuffer->IsAttached());
|
||||
return mBuffer->AsTiledLayerComposer();
|
||||
}
|
||||
|
||||
LayerRenderState
|
||||
ThebesLayerComposite::GetRenderState()
|
||||
{
|
||||
if (!mBuffer || mDestroyed) {
|
||||
if (!mBuffer || !mBuffer->IsAttached() || mDestroyed) {
|
||||
return LayerRenderState();
|
||||
}
|
||||
return mBuffer->GetRenderState();
|
||||
@ -91,10 +88,14 @@ void
|
||||
ThebesLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
const nsIntRect& aClipRect)
|
||||
{
|
||||
if (!mBuffer) {
|
||||
if (!mBuffer || !mBuffer->IsAttached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mBuffer->GetCompositor() == mCompositeManager->GetCompositor() &&
|
||||
mBuffer->GetLayer() == this,
|
||||
"buffer is corrupted");
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(GetEffectiveTransform(), transform);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
@ -145,14 +146,19 @@ ThebesLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
}
|
||||
|
||||
CompositableHost*
|
||||
ThebesLayerComposite::GetCompositableHost() {
|
||||
return mBuffer.get();
|
||||
ThebesLayerComposite::GetCompositableHost()
|
||||
{
|
||||
if (mBuffer->IsAttached()) {
|
||||
return mBuffer.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerComposite::CleanupResources()
|
||||
{
|
||||
if (mBuffer) {
|
||||
if (mBuffer) {
|
||||
mBuffer->Detach();
|
||||
}
|
||||
mBuffer = nullptr;
|
||||
@ -283,7 +289,7 @@ ThebesLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix)
|
||||
{
|
||||
ThebesLayer::PrintInfo(aTo, aPrefix);
|
||||
aTo += "\n";
|
||||
if (mBuffer) {
|
||||
if (mBuffer && mBuffer->IsAttached()) {
|
||||
nsAutoCString pfx(aPrefix);
|
||||
pfx += " ";
|
||||
mBuffer->PrintInfo(aTo, pfx.get());
|
||||
|
@ -319,6 +319,7 @@ CompositorD3D11::GetTextureFactoryIdentifier()
|
||||
{
|
||||
TextureFactoryIdentifier ident;
|
||||
ident.mMaxTextureSize = GetMaxTextureSize();
|
||||
ident.mParentProcessId = XRE_GetProcessType();
|
||||
ident.mParentBackend = LAYERS_D3D11;
|
||||
return ident;
|
||||
}
|
||||
@ -566,39 +567,47 @@ CompositorD3D11::BeginFrame(const Rect* aClipRectIn,
|
||||
Rect* aClipRectOut,
|
||||
Rect* aRenderBoundsOut)
|
||||
{
|
||||
VerifyBufferSize();
|
||||
UpdateRenderTarget();
|
||||
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
if (rect.IsEmpty()) {
|
||||
if (mSize.width == 0 || mSize.height == 0) {
|
||||
*aRenderBoundsOut = Rect();
|
||||
return;
|
||||
}
|
||||
|
||||
mDefaultRT->SetSize(IntSize(rect.width, rect.height));
|
||||
|
||||
mContext->IASetInputLayout(mAttachments->mInputLayout);
|
||||
|
||||
ID3D11Buffer* buffer = mAttachments->mVertexBuffer;
|
||||
UINT size = sizeof(Vertex);
|
||||
UINT offset = 0;
|
||||
mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset);
|
||||
SetRenderTarget(mDefaultRT);
|
||||
|
||||
if (aClipRectOut) {
|
||||
*aClipRectOut = Rect(0, 0, rect.width, rect.height);
|
||||
*aClipRectOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
if (aRenderBoundsOut) {
|
||||
*aRenderBoundsOut = Rect(0, 0, rect.width, rect.height);
|
||||
*aRenderBoundsOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
|
||||
D3D11_RECT scissor;
|
||||
if (aClipRectIn) {
|
||||
scissor.left = aClipRectIn->x;
|
||||
scissor.right = aClipRectIn->XMost();
|
||||
scissor.top = aClipRectIn->y;
|
||||
scissor.bottom = aClipRectIn->YMost();
|
||||
} else {
|
||||
scissor.left = scissor.top = 0;
|
||||
scissor.right = mSize.width;
|
||||
scissor.bottom = mSize.height;
|
||||
}
|
||||
mContext->RSSetScissorRects(1, &scissor);
|
||||
|
||||
FLOAT black[] = { 0, 0, 0, 0 };
|
||||
mContext->ClearRenderTargetView(mDefaultRT->mRTView, black);
|
||||
|
||||
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||
mContext->RSSetState(mAttachments->mRasterizerState);
|
||||
|
||||
SetRenderTarget(mDefaultRT);
|
||||
}
|
||||
|
||||
void
|
||||
@ -640,43 +649,41 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
|
||||
memcpy(&mVSConstants.projection, &projection, sizeof(mVSConstants.projection));
|
||||
}
|
||||
|
||||
const nsIntSize&
|
||||
CompositorD3D11::GetWidgetSize()
|
||||
void
|
||||
CompositorD3D11::EnsureSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
mSize = rect.Size();
|
||||
|
||||
return mSize;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::VerifyBufferSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
mSwapChain->GetDesc(&swapDesc);
|
||||
|
||||
if ((swapDesc.BufferDesc.Width == rect.width &&
|
||||
swapDesc.BufferDesc.Height == rect.height) || rect.IsEmpty()) {
|
||||
if ((swapDesc.BufferDesc.Width == mSize.width &&
|
||||
swapDesc.BufferDesc.Height == mSize.height) ||
|
||||
mSize.width == 0 || mSize.height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDefaultRT = nullptr;
|
||||
|
||||
if (gfxWindowsPlatform::IsOptimus()) {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
#ifdef MOZ_METRO
|
||||
} else if (IsRunningInWindowsMetro()) {
|
||||
mSwapChain->ResizeBuffers(2, rect.width, rect.height,
|
||||
mSwapChain->ResizeBuffers(2, mSize.width, mSize.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
#endif
|
||||
} else {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
|
||||
}
|
||||
@ -685,6 +692,9 @@ CompositorD3D11::VerifyBufferSize()
|
||||
void
|
||||
CompositorD3D11::UpdateRenderTarget()
|
||||
{
|
||||
EnsureSize();
|
||||
VerifyBufferSize();
|
||||
|
||||
if (mDefaultRT) {
|
||||
return;
|
||||
}
|
||||
@ -699,6 +709,7 @@ CompositorD3D11::UpdateRenderTarget()
|
||||
}
|
||||
|
||||
mDefaultRT = new CompositingRenderTargetD3D11(backBuf);
|
||||
mDefaultRT->SetSize(mSize);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -706,7 +717,6 @@ CompositorD3D11::CreateShaders()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
|
||||
hr = mDevice->CreateVertexShader(LayerQuadVS,
|
||||
sizeof(LayerQuadVS),
|
||||
nullptr,
|
||||
@ -824,7 +834,7 @@ CompositorD3D11::PaintToTarget()
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mTarget->SetSource(tmpSurface);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
mTarget->Paint();
|
||||
|
||||
mContext->Unmap(readTexture, 0);
|
||||
|
@ -137,11 +137,20 @@ public:
|
||||
virtual void NotifyLayersTransaction() MOZ_OVERRIDE { }
|
||||
|
||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE;
|
||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
|
||||
{
|
||||
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
|
||||
"You should not do that outside of BeginFrame, so the best we can do is return "
|
||||
"the last size we got, that might not be up to date. So you probably shouldn't "
|
||||
"use this method.");
|
||||
return mSize;
|
||||
}
|
||||
|
||||
ID3D11Device* GetDevice() { return mDevice; }
|
||||
|
||||
private:
|
||||
// ensure mSize is up to date with respect to mWidget
|
||||
void EnsureSize();
|
||||
void VerifyBufferSize();
|
||||
void UpdateRenderTarget();
|
||||
bool CreateShaders();
|
||||
@ -161,9 +170,7 @@ private:
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
nsIWidget* mWidget;
|
||||
// GetWidgetSize requires us to return a reference to an nsIntSize. Since we
|
||||
// don't otherwise keep this value around, we need mSize to avoid a dangling
|
||||
// reference problem.
|
||||
|
||||
nsIntSize mSize;
|
||||
|
||||
HWND mHwnd;
|
||||
|
@ -77,7 +77,7 @@ DeprecatedTextureClientD3D11::~DeprecatedTextureClientD3D11()
|
||||
ClearDT();
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType)
|
||||
{
|
||||
@ -87,7 +87,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
||||
mTexture->GetDesc(&desc);
|
||||
|
||||
if (desc.Width == aSize.width && desc.Height == aSize.height) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
mTexture = nullptr;
|
||||
@ -109,7 +109,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
||||
|
||||
if (FAILED(hr)) {
|
||||
LOGD3D11("Error creating texture for client!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<IDXGIResource> resource;
|
||||
@ -126,6 +126,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
||||
aType == gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
|
||||
mContentType = aType;
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
return aType == TEXTURE_CONTENT;
|
||||
}
|
||||
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize,
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual gfxASurface* LockSurface() MOZ_OVERRIDE;
|
||||
|
@ -46,7 +46,7 @@ RenderColorLayerD3D9(ColorLayer* aLayer, LayerManagerD3D9 *aManager)
|
||||
color[2] = (float)(layerColor.b * opacity);
|
||||
color[3] = (float)(opacity);
|
||||
|
||||
aManager->device()->SetPixelShaderConstantF(0, color, 1);
|
||||
aManager->device()->SetPixelShaderConstantF(CBvColor, color, 1);
|
||||
|
||||
aManager->SetShaderMode(DeviceManagerD3D9::SOLIDCOLORLAYER,
|
||||
aLayer->GetMaskLayer());
|
||||
|
592
gfx/layers/d3d9/CompositorD3D9.cpp
Normal file
592
gfx/layers/d3d9/CompositorD3D9.cpp
Normal file
@ -0,0 +1,592 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "CompositorD3D9.h"
|
||||
#include "LayerManagerD3D9Shaders.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/layers/ImageHost.h"
|
||||
#include "mozilla/layers/ContentHost.h"
|
||||
#include "mozilla/layers/Effects.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "Nv3DVUtils.h"
|
||||
#include "gfxFailure.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
CompositorD3D9::CompositorD3D9(nsIWidget *aWidget)
|
||||
: mWidget(aWidget)
|
||||
{
|
||||
sBackend = LAYERS_D3D9;
|
||||
}
|
||||
|
||||
CompositorD3D9::~CompositorD3D9()
|
||||
{
|
||||
mSwapChain = nullptr;
|
||||
mDeviceManager = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorD3D9::Initialize()
|
||||
{
|
||||
if (!gfxPlatform::CanUseDirect3D9()) {
|
||||
NS_WARNING("Direct3D 9-accelerated layers are not supported on this system.");
|
||||
return false;
|
||||
}
|
||||
|
||||
mDeviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
|
||||
if (!mDeviceManager) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSwapChain = mDeviceManager->
|
||||
CreateSwapChain((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
|
||||
if (!mSwapChain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TextureFactoryIdentifier
|
||||
CompositorD3D9::GetTextureFactoryIdentifier()
|
||||
{
|
||||
TextureFactoryIdentifier ident;
|
||||
ident.mMaxTextureSize = GetMaxTextureSize();
|
||||
ident.mParentBackend = LAYERS_D3D9;
|
||||
ident.mParentProcessId = XRE_GetProcessType();
|
||||
return ident;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorD3D9::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
|
||||
{
|
||||
int32_t maxTextureSize = GetMaxTextureSize();
|
||||
|
||||
if (aSize.width > maxTextureSize || aSize.height > maxTextureSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t
|
||||
CompositorD3D9::GetMaxTextureSize() const
|
||||
{
|
||||
return mDeviceManager->GetMaxTextureSize();
|
||||
}
|
||||
|
||||
TemporaryRef<CompositingRenderTarget>
|
||||
CompositorD3D9::CreateRenderTarget(const gfx::IntRect &aRect,
|
||||
SurfaceInitMode aInit)
|
||||
{
|
||||
RefPtr<IDirect3DTexture9> texture;
|
||||
HRESULT hr = device()->CreateTexture(aRect.width, aRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, byRef(texture),
|
||||
NULL);
|
||||
if (FAILED(hr)) {
|
||||
ReportFailure(NS_LITERAL_CSTRING("CompositorD3D9::CreateRenderTarget: Failed to create texture"),
|
||||
hr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CompositingRenderTargetD3D9> rt =
|
||||
new CompositingRenderTargetD3D9(texture, aInit, IntSize(aRect.width, aRect.height));
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
TemporaryRef<CompositingRenderTarget>
|
||||
CompositorD3D9::CreateRenderTargetFromSource(const gfx::IntRect &aRect,
|
||||
const CompositingRenderTarget *aSource)
|
||||
{
|
||||
RefPtr<IDirect3DTexture9> texture;
|
||||
HRESULT hr = device()->CreateTexture(aRect.width, aRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, byRef(texture),
|
||||
NULL);
|
||||
if (FAILED(hr)) {
|
||||
ReportFailure(NS_LITERAL_CSTRING("CompositorD3D9::CreateRenderTargetFromSource: Failed to create texture"),
|
||||
hr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aSource) {
|
||||
nsRefPtr<IDirect3DSurface9> sourceSurface =
|
||||
static_cast<const CompositingRenderTargetD3D9*>(aSource)->GetD3D9Surface();
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> destSurface;
|
||||
hr = texture->GetSurfaceLevel(0, getter_AddRefs(destSurface));
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to get texture surface level for dest.");
|
||||
}
|
||||
|
||||
if (sourceSurface && destSurface) {
|
||||
RECT sourceRect;
|
||||
sourceRect.left = aRect.x;
|
||||
sourceRect.right = aRect.XMost();
|
||||
sourceRect.top = aRect.y;
|
||||
sourceRect.bottom = aRect.YMost();
|
||||
RECT destRect;
|
||||
destRect.left = 0;
|
||||
destRect.right = aRect.width;
|
||||
destRect.top = 0;
|
||||
destRect.bottom = aRect.height;
|
||||
|
||||
// copy the source to the dest
|
||||
hr = device()->StretchRect(sourceSurface,
|
||||
&sourceRect,
|
||||
destSurface,
|
||||
&destRect,
|
||||
D3DTEXF_NONE);
|
||||
if (FAILED(hr)) {
|
||||
ReportFailure(NS_LITERAL_CSTRING("CompositorD3D9::CreateRenderTargetFromSource: Failed to update texture"),
|
||||
hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<CompositingRenderTargetD3D9> rt =
|
||||
new CompositingRenderTargetD3D9(texture,
|
||||
INIT_MODE_NONE,
|
||||
IntSize(aRect.width, aRect.height));
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::SetRenderTarget(CompositingRenderTarget *aRenderTarget)
|
||||
{
|
||||
MOZ_ASSERT(aRenderTarget);
|
||||
RefPtr<CompositingRenderTargetD3D9> oldRT = mCurrentRT;
|
||||
mCurrentRT = static_cast<CompositingRenderTargetD3D9*>(aRenderTarget);
|
||||
mCurrentRT->BindRenderTarget(device());
|
||||
PrepareViewport(mCurrentRT->GetSize(), gfxMatrix());
|
||||
}
|
||||
|
||||
static DeviceManagerD3D9::ShaderMode
|
||||
ShaderModeForEffectType(EffectTypes aEffectType)
|
||||
{
|
||||
switch (aEffectType) {
|
||||
case EFFECT_SOLID_COLOR:
|
||||
return DeviceManagerD3D9::SOLIDCOLORLAYER;
|
||||
case EFFECT_BGRA:
|
||||
case EFFECT_RENDER_TARGET:
|
||||
return DeviceManagerD3D9::RGBALAYER;
|
||||
case EFFECT_BGRX:
|
||||
return DeviceManagerD3D9::RGBLAYER;
|
||||
case EFFECT_YCBCR:
|
||||
return DeviceManagerD3D9::YCBCRLAYER;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Bad effect type");
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::DrawQuad(const gfx::Rect &aRect, const gfx::Rect &aClipRect,
|
||||
const EffectChain &aEffectChain,
|
||||
gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform,
|
||||
const gfx::Point &aOffset)
|
||||
{
|
||||
MOZ_ASSERT(mCurrentRT, "No render target");
|
||||
device()->SetVertexShaderConstantF(CBmLayerTransform, &aTransform._11, 4);
|
||||
|
||||
float renderTargetOffset[] = { aOffset.x, aOffset.y, 0, 0 };
|
||||
device()->SetVertexShaderConstantF(CBvRenderTargetOffset,
|
||||
renderTargetOffset,
|
||||
1);
|
||||
device()->SetVertexShaderConstantF(CBvLayerQuad,
|
||||
ShaderConstantRect(aRect.x,
|
||||
aRect.y,
|
||||
aRect.width,
|
||||
aRect.height),
|
||||
1);
|
||||
bool target = false;
|
||||
|
||||
if (aEffectChain.mPrimaryEffect->mType != EFFECT_SOLID_COLOR) {
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will use only the
|
||||
* first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = aOpacity;
|
||||
device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1);
|
||||
}
|
||||
|
||||
bool isPremultiplied = true;
|
||||
|
||||
MaskType maskType = MaskNone;
|
||||
|
||||
if (aEffectChain.mSecondaryEffects[EFFECT_MASK]) {
|
||||
if (aTransform.Is2D()) {
|
||||
maskType = Mask2d;
|
||||
} else {
|
||||
maskType = Mask3d;
|
||||
}
|
||||
}
|
||||
|
||||
RECT scissor;
|
||||
scissor.left = aClipRect.x;
|
||||
scissor.right = aClipRect.XMost();
|
||||
scissor.top = aClipRect.y;
|
||||
scissor.bottom = aClipRect.YMost();
|
||||
device()->SetScissorRect(&scissor);
|
||||
|
||||
uint32_t maskTexture = 0;
|
||||
switch (aEffectChain.mPrimaryEffect->mType) {
|
||||
case EFFECT_SOLID_COLOR:
|
||||
{
|
||||
// output color is premultiplied, so we need to adjust all channels.
|
||||
Color layerColor =
|
||||
static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())->mColor;
|
||||
float color[4];
|
||||
color[0] = layerColor.r * layerColor.a * aOpacity;
|
||||
color[1] = layerColor.g * layerColor.a * aOpacity;
|
||||
color[2] = layerColor.b * layerColor.a * aOpacity;
|
||||
color[3] = layerColor.a * aOpacity;
|
||||
|
||||
device()->SetPixelShaderConstantF(CBvColor, color, 1);
|
||||
|
||||
maskTexture = mDeviceManager
|
||||
->SetShaderMode(DeviceManagerD3D9::SOLIDCOLORLAYER, maskType);
|
||||
}
|
||||
break;
|
||||
case EFFECT_RENDER_TARGET:
|
||||
case EFFECT_BGRX:
|
||||
case EFFECT_BGRA:
|
||||
{
|
||||
TexturedEffect* texturedEffect =
|
||||
static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
|
||||
|
||||
Rect textureCoords = texturedEffect->mTextureCoords;
|
||||
device()->SetVertexShaderConstantF(CBvTextureCoords,
|
||||
ShaderConstantRect(
|
||||
textureCoords.x,
|
||||
textureCoords.y,
|
||||
textureCoords.width,
|
||||
textureCoords.height),
|
||||
1);
|
||||
|
||||
SetSamplerForFilter(texturedEffect->mFilter);
|
||||
|
||||
TextureSourceD3D9* source = texturedEffect->mTexture->AsSourceD3D9();
|
||||
device()->SetTexture(0, source->GetD3D9Texture());
|
||||
|
||||
maskTexture = mDeviceManager
|
||||
->SetShaderMode(ShaderModeForEffectType(aEffectChain.mPrimaryEffect->mType),
|
||||
maskType);
|
||||
|
||||
isPremultiplied = texturedEffect->mPremultiplied;
|
||||
}
|
||||
break;
|
||||
case EFFECT_YCBCR:
|
||||
{
|
||||
EffectYCbCr* ycbcrEffect =
|
||||
static_cast<EffectYCbCr*>(aEffectChain.mPrimaryEffect.get());
|
||||
|
||||
SetSamplerForFilter(FILTER_LINEAR);
|
||||
|
||||
Rect textureCoords = ycbcrEffect->mTextureCoords;
|
||||
device()->SetVertexShaderConstantF(CBvTextureCoords,
|
||||
ShaderConstantRect(
|
||||
textureCoords.x,
|
||||
textureCoords.y,
|
||||
textureCoords.width,
|
||||
textureCoords.height),
|
||||
1);
|
||||
|
||||
TextureSourceD3D9* source = ycbcrEffect->mTexture->AsSourceD3D9();
|
||||
TextureSourceD3D9::YCbCrTextures textures = source->GetYCbCrTextures();
|
||||
|
||||
/*
|
||||
* Send 3d control data and metadata
|
||||
*/
|
||||
if (mDeviceManager->GetNv3DVUtils()) {
|
||||
Nv_Stereo_Mode mode;
|
||||
switch (textures.mStereoMode) {
|
||||
case STEREO_MODE_LEFT_RIGHT:
|
||||
mode = NV_STEREO_MODE_LEFT_RIGHT;
|
||||
break;
|
||||
case STEREO_MODE_RIGHT_LEFT:
|
||||
mode = NV_STEREO_MODE_RIGHT_LEFT;
|
||||
break;
|
||||
case STEREO_MODE_BOTTOM_TOP:
|
||||
mode = NV_STEREO_MODE_BOTTOM_TOP;
|
||||
break;
|
||||
case STEREO_MODE_TOP_BOTTOM:
|
||||
mode = NV_STEREO_MODE_TOP_BOTTOM;
|
||||
break;
|
||||
case STEREO_MODE_MONO:
|
||||
mode = NV_STEREO_MODE_MONO;
|
||||
break;
|
||||
}
|
||||
|
||||
// Send control data even in mono case so driver knows to leave stereo mode.
|
||||
mDeviceManager->GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE);
|
||||
|
||||
if (textures.mStereoMode != STEREO_MODE_MONO) {
|
||||
mDeviceManager->GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> renderTarget;
|
||||
device()->GetRenderTarget(0, getter_AddRefs(renderTarget));
|
||||
mDeviceManager->GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)aRect.width,
|
||||
(unsigned int)aRect.height,
|
||||
(HANDLE)(textures.mY),
|
||||
(HANDLE)(renderTarget));
|
||||
}
|
||||
}
|
||||
|
||||
// Linear scaling is default here, adhering to mFilter is difficult since
|
||||
// presumably even with point filtering we'll still want chroma upsampling
|
||||
// to be linear. In the current approach we can't.
|
||||
device()->SetTexture(0, textures.mY);
|
||||
device()->SetTexture(1, textures.mCb);
|
||||
device()->SetTexture(2, textures.mCr);
|
||||
maskTexture = mDeviceManager->SetShaderMode(DeviceManagerD3D9::YCBCRLAYER, maskType);
|
||||
}
|
||||
break;
|
||||
case EFFECT_COMPONENT_ALPHA:
|
||||
{
|
||||
EffectComponentAlpha* effectComponentAlpha =
|
||||
static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
|
||||
TextureSourceD3D9* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceD3D9();
|
||||
TextureSourceD3D9* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceD3D9();
|
||||
|
||||
Rect textureCoords = effectComponentAlpha->mTextureCoords;
|
||||
device()->SetVertexShaderConstantF(CBvTextureCoords,
|
||||
ShaderConstantRect(
|
||||
textureCoords.x,
|
||||
textureCoords.y,
|
||||
textureCoords.width,
|
||||
textureCoords.height),
|
||||
1);
|
||||
|
||||
SetSamplerForFilter(effectComponentAlpha->mFilter);
|
||||
SetMask(aEffectChain, maskTexture);
|
||||
|
||||
maskTexture = mDeviceManager->SetShaderMode(DeviceManagerD3D9::COMPONENTLAYERPASS1, maskType);
|
||||
device()->SetTexture(0, sourceOnBlack->GetD3D9Texture());
|
||||
device()->SetTexture(1, sourceOnWhite->GetD3D9Texture());
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
|
||||
device()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
|
||||
device()->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
maskTexture = mDeviceManager->SetShaderMode(DeviceManagerD3D9::COMPONENTLAYERPASS2, maskType);
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
device()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
// Restore defaults
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
device()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
device()->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
|
||||
device()->SetTexture(1, NULL);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
NS_WARNING("Unknown shader type");
|
||||
return;
|
||||
}
|
||||
|
||||
SetMask(aEffectChain, maskTexture);
|
||||
|
||||
if (!isPremultiplied) {
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
device()->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
}
|
||||
|
||||
HRESULT hr = device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
if (!isPremultiplied) {
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
device()->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::SetMask(const EffectChain &aEffectChain, uint32_t aMaskTexture)
|
||||
{
|
||||
EffectMask *maskEffect =
|
||||
static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EFFECT_MASK].get());
|
||||
if (!maskEffect) {
|
||||
return;
|
||||
}
|
||||
|
||||
TextureSourceD3D9 *source = maskEffect->mMaskTexture->AsSourceD3D9();
|
||||
|
||||
MOZ_ASSERT(aMaskTexture >= 0);
|
||||
device()->SetTexture(aMaskTexture, source->GetD3D9Texture());
|
||||
|
||||
const gfx::Matrix4x4& maskTransform = maskEffect->mMaskTransform;
|
||||
NS_ASSERTION(maskTransform.Is2D(), "How did we end up with a 3D transform here?!");
|
||||
Rect bounds = Rect(Point(), Size(maskEffect->mSize));
|
||||
bounds = maskTransform.As2D().TransformBounds(bounds);
|
||||
|
||||
device()->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
|
||||
ShaderConstantRect(bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
bounds.height),
|
||||
1);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::BeginFrame(const Rect *aClipRectIn,
|
||||
const gfxMatrix& aTransform,
|
||||
const Rect& aRenderBounds,
|
||||
Rect *aClipRectOut,
|
||||
Rect *aRenderBoundsOut)
|
||||
{
|
||||
if (!mSwapChain->PrepareForRendering()) {
|
||||
return;
|
||||
}
|
||||
mDeviceManager->SetupRenderState();
|
||||
|
||||
EnsureSize();
|
||||
|
||||
device()->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 0, 0);
|
||||
device()->BeginScene();
|
||||
|
||||
if (aClipRectOut) {
|
||||
*aClipRectOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
if (aRenderBoundsOut) {
|
||||
*aRenderBoundsOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
|
||||
RECT r;
|
||||
if (aClipRectIn) {
|
||||
r.left = (LONG)aClipRectIn->x;
|
||||
r.top = (LONG)aClipRectIn->y;
|
||||
r.right = (LONG)(aClipRectIn->x + aClipRectIn->width);
|
||||
r.bottom = (LONG)(aClipRectIn->y + aClipRectIn->height);
|
||||
} else {
|
||||
r.left = r.top = 0;
|
||||
r.right = mSize.width;
|
||||
r.bottom = mSize.height;
|
||||
}
|
||||
device()->SetScissorRect(&r);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer = mSwapChain->GetBackBuffer();
|
||||
mDefaultRT = new CompositingRenderTargetD3D9(backBuffer,
|
||||
INIT_MODE_CLEAR,
|
||||
IntSize(mSize.width, mSize.height));
|
||||
SetRenderTarget(mDefaultRT);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::EndFrame()
|
||||
{
|
||||
device()->EndScene();
|
||||
|
||||
if (!!mTarget) {
|
||||
PaintToTarget();
|
||||
} else {
|
||||
mSwapChain->Present();
|
||||
}
|
||||
|
||||
mCurrentRT = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::PrepareViewport(const gfx::IntSize& aSize,
|
||||
const gfxMatrix &aWorldTransform)
|
||||
{
|
||||
gfx3DMatrix viewMatrix;
|
||||
/*
|
||||
* Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
|
||||
* <1.0, -1.0> bottomright)
|
||||
*/
|
||||
viewMatrix._11 = 2.0f / aSize.width;
|
||||
viewMatrix._22 = -2.0f / aSize.height;
|
||||
viewMatrix._41 = -1.0f;
|
||||
viewMatrix._42 = 1.0f;
|
||||
|
||||
viewMatrix = gfx3DMatrix::From2D(aWorldTransform) * viewMatrix;
|
||||
|
||||
HRESULT hr = device()->SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to set projection matrix");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::EnsureSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
mSize = rect.Size();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::SetSamplerForFilter(Filter aFilter)
|
||||
{
|
||||
switch (aFilter) {
|
||||
case FILTER_LINEAR:
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
return;
|
||||
case FILTER_POINT:
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||
return;
|
||||
default:
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::PaintToTarget()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuff;
|
||||
nsRefPtr<IDirect3DSurface9> destSurf;
|
||||
device()->GetRenderTarget(0, getter_AddRefs(backBuff));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuff->GetDesc(&desc);
|
||||
|
||||
device()->CreateOffscreenPlainSurface(desc.Width, desc.Height,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(destSurf), NULL);
|
||||
|
||||
device()->GetRenderTargetData(backBuff, destSurf);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
destSurf->LockRect(&rect, NULL, D3DLOCK_READONLY);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface((unsigned char*)rect.pBits,
|
||||
gfxIntSize(desc.Width, desc.Height),
|
||||
rect.Pitch,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
mTarget->SetSource(imageSurface);
|
||||
mTarget->Paint();
|
||||
destSurf->UnlockRect();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D9::ReportFailure(const nsACString &aMsg, HRESULT aCode)
|
||||
{
|
||||
// We could choose to abort here when hr == E_OUTOFMEMORY.
|
||||
nsCString msg;
|
||||
msg.Append(aMsg);
|
||||
msg.AppendLiteral(" Error code: ");
|
||||
msg.AppendInt(uint32_t(aCode));
|
||||
NS_WARNING(msg.BeginReading());
|
||||
|
||||
gfx::LogFailure(msg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
142
gfx/layers/d3d9/CompositorD3D9.h
Normal file
142
gfx/layers/d3d9/CompositorD3D9.h
Normal file
@ -0,0 +1,142 @@
|
||||
/* -*- 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_COMPOSITORD3D9_H
|
||||
#define MOZILLA_GFX_COMPOSITORD3D9_H
|
||||
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/TextureD3D9.h"
|
||||
#include "DeviceManagerD3D9.h"
|
||||
|
||||
class nsWidget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CompositorD3D9 : public Compositor
|
||||
{
|
||||
public:
|
||||
CompositorD3D9(nsIWidget *aWidget);
|
||||
~CompositorD3D9();
|
||||
|
||||
virtual bool Initialize() MOZ_OVERRIDE;
|
||||
virtual void Destroy() MOZ_OVERRIDE {}
|
||||
|
||||
virtual TextureFactoryIdentifier
|
||||
GetTextureFactoryIdentifier() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE;
|
||||
virtual int32_t GetMaxTextureSize() const MOZ_FINAL;
|
||||
|
||||
virtual void SetTargetContext(gfxContext *aTarget) MOZ_OVERRIDE
|
||||
{
|
||||
mTarget = aTarget;
|
||||
}
|
||||
|
||||
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE {}
|
||||
|
||||
virtual TemporaryRef<CompositingRenderTarget>
|
||||
CreateRenderTarget(const gfx::IntRect &aRect,
|
||||
SurfaceInitMode aInit) MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<CompositingRenderTarget>
|
||||
CreateRenderTargetFromSource(const gfx::IntRect &aRect,
|
||||
const CompositingRenderTarget *aSource) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetRenderTarget(CompositingRenderTarget *aSurface);
|
||||
virtual CompositingRenderTarget* GetCurrentRenderTarget() MOZ_OVERRIDE
|
||||
{
|
||||
return mCurrentRT;
|
||||
}
|
||||
|
||||
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) MOZ_OVERRIDE {}
|
||||
|
||||
virtual void DrawQuad(const gfx::Rect &aRect, const gfx::Rect &aClipRect,
|
||||
const EffectChain &aEffectChain,
|
||||
gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform,
|
||||
const gfx::Point &aOffset) MOZ_OVERRIDE;
|
||||
|
||||
virtual void BeginFrame(const gfx::Rect *aClipRectIn,
|
||||
const gfxMatrix& aTransform,
|
||||
const gfx::Rect& aRenderBounds,
|
||||
gfx::Rect *aClipRectOut = nullptr,
|
||||
gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
virtual void EndFrame() MOZ_OVERRIDE;
|
||||
|
||||
virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE {}
|
||||
|
||||
virtual void AbortFrame() MOZ_OVERRIDE {}
|
||||
|
||||
virtual void PrepareViewport(const gfx::IntSize& aSize,
|
||||
const gfxMatrix& aWorldTransform) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE{ return true; }
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
virtual const char* Name() const MOZ_OVERRIDE { return "Direct3D9"; }
|
||||
#endif
|
||||
|
||||
virtual void NotifyLayersTransaction() MOZ_OVERRIDE {}
|
||||
|
||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
|
||||
{
|
||||
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
|
||||
"You should not do that outside of BeginFrame, so the best we can do is return "
|
||||
"the last size we got, that might not be up to date. So you probably shouldn't "
|
||||
"use this method.");
|
||||
return mSize;
|
||||
}
|
||||
|
||||
IDirect3DDevice9* device() const { return mDeviceManager->device(); }
|
||||
|
||||
/**
|
||||
* Declare an offset to use when rendering layers. This will be ignored when
|
||||
* rendering to a target instead of the screen.
|
||||
*/
|
||||
virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) MOZ_OVERRIDE
|
||||
{
|
||||
if (aOffset.x || aOffset.y) {
|
||||
NS_RUNTIMEABORT("SetScreenRenderOffset not supported by CompositorD3D9.");
|
||||
}
|
||||
// If the offset is 0, 0 that's okay.
|
||||
}
|
||||
|
||||
virtual TemporaryRef<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE { return nullptr; }
|
||||
private:
|
||||
// ensure mSize is up to date with respect to mWidget
|
||||
void EnsureSize();
|
||||
void SetSamplerForFilter(gfx::Filter aFilter);
|
||||
void PaintToTarget();
|
||||
void SetMask(const EffectChain &aEffectChain, uint32_t aMaskTexture);
|
||||
|
||||
void ReportFailure(const nsACString &aMsg, HRESULT aCode);
|
||||
|
||||
/* Device manager instance for this compositor */
|
||||
nsRefPtr<DeviceManagerD3D9> mDeviceManager;
|
||||
|
||||
/* Swap chain associated with this compositor */
|
||||
nsRefPtr<SwapChainD3D9> mSwapChain;
|
||||
|
||||
/* Widget associated with this layer manager */
|
||||
nsIWidget *mWidget;
|
||||
|
||||
/*
|
||||
* Context target, NULL when drawing directly to our swap chain.
|
||||
*/
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
RefPtr<CompositingRenderTargetD3D9> mDefaultRT;
|
||||
RefPtr<CompositingRenderTargetD3D9> mCurrentRT;
|
||||
|
||||
nsIntSize mSize;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -12,6 +12,7 @@
|
||||
#include "Nv3DVUtils.h"
|
||||
#include "plstr.h"
|
||||
#include <algorithm>
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -78,6 +79,16 @@ SwapChainD3D9::Init(HWND hWnd)
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<IDirect3DSurface9>
|
||||
SwapChainD3D9::GetBackBuffer()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
return backBuffer.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
SwapChainD3D9::PrepareForRendering()
|
||||
{
|
||||
@ -95,10 +106,7 @@ SwapChainD3D9::PrepareForRendering()
|
||||
}
|
||||
|
||||
if (mSwapChain) {
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer = GetBackBuffer();
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuffer->GetDesc(&desc);
|
||||
@ -116,10 +124,7 @@ SwapChainD3D9::PrepareForRendering()
|
||||
return false;
|
||||
}
|
||||
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
|
||||
backBuffer = GetBackBuffer();
|
||||
mDeviceManager->device()->SetRenderTarget(0, backBuffer);
|
||||
|
||||
return true;
|
||||
@ -139,6 +144,12 @@ SwapChainD3D9::Present(const nsIntRect &aRect)
|
||||
mSwapChain->Present(&r, &r, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainD3D9::Present()
|
||||
{
|
||||
mSwapChain->Present(NULL, NULL, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainD3D9::Reset()
|
||||
{
|
||||
@ -148,9 +159,12 @@ SwapChainD3D9::Reset()
|
||||
#define HAS_CAP(a, b) (((a) & (b)) == (b))
|
||||
#define LACKS_CAP(a, b) !(((a) & (b)) == (b))
|
||||
|
||||
uint32_t DeviceManagerD3D9::sMaskQuadRegister = 11;
|
||||
|
||||
DeviceManagerD3D9::DeviceManagerD3D9()
|
||||
: mDeviceResetCount(0)
|
||||
, mMaxTextureSize(0)
|
||||
, mTextureAddressingMode(D3DTADDRESS_CLAMP)
|
||||
, mHasDynamicTextures(false)
|
||||
, mDeviceWasRemoved(false)
|
||||
{
|
||||
@ -161,9 +175,6 @@ DeviceManagerD3D9::~DeviceManagerD3D9()
|
||||
LayerManagerD3D9::OnDeviceManagerDestroy(this);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(DeviceManagerD3D9)
|
||||
NS_IMPL_RELEASE(DeviceManagerD3D9)
|
||||
|
||||
bool
|
||||
DeviceManagerD3D9::Init()
|
||||
{
|
||||
@ -496,12 +507,12 @@ DeviceManagerD3D9::SetupRenderState()
|
||||
mDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, mTextureAddressingMode);
|
||||
}
|
||||
|
||||
already_AddRefed<SwapChainD3D9>
|
||||
@ -533,7 +544,7 @@ DeviceManagerD3D9::CreateSwapChain(HWND hWnd)
|
||||
*/
|
||||
bool
|
||||
LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
|
||||
uint32_t aMaskQuadTexture, uint32_t aMaskTexRegister)
|
||||
uint32_t aMaskTexRegister)
|
||||
{
|
||||
gfxIntSize size;
|
||||
nsRefPtr<IDirect3DTexture9> texture =
|
||||
@ -549,7 +560,7 @@ LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
|
||||
gfxRect bounds = gfxRect(gfxPoint(), size);
|
||||
bounds = maskTransform.TransformBounds(bounds);
|
||||
|
||||
aDevice->SetVertexShaderConstantF(aMaskQuadTexture,
|
||||
aDevice->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
|
||||
ShaderConstantRect((float)bounds.x,
|
||||
(float)bounds.y,
|
||||
(float)bounds.width,
|
||||
@ -560,57 +571,10 @@ LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
|
||||
uint32_t
|
||||
DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, MaskType aMaskType)
|
||||
{
|
||||
if (aMask) {
|
||||
// register allocations are taken from LayerManagerD3D9Shaders.h after
|
||||
// the shaders are compiled (genshaders.sh)
|
||||
const uint32_t maskQuadRegister = 11;
|
||||
uint32_t maskTexRegister;
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBPSMask);
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case RGBALAYER:
|
||||
if (aIs2D) {
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBAPSMask);
|
||||
} else {
|
||||
mDevice->SetVertexShader(mLayerVSMask3D);
|
||||
mDevice->SetPixelShader(mRGBAPSMask3D);
|
||||
}
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case COMPONENTLAYERPASS1:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass1PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case COMPONENTLAYERPASS2:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass2PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mYCbCrPSMask);
|
||||
maskTexRegister = 3;
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mSolidColorPSMask);
|
||||
maskTexRegister = 0;
|
||||
break;
|
||||
}
|
||||
if (!LoadMaskTexture(aMask, mDevice, maskQuadRegister, maskTexRegister)) {
|
||||
// if we can't load the mask, fall back to unmasked rendering
|
||||
NS_WARNING("Could not load texture for mask layer.");
|
||||
SetShaderMode(aMode, nullptr, true);
|
||||
}
|
||||
} else {
|
||||
if (aMaskType == MaskNone) {
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
@ -637,6 +601,66 @@ DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
|
||||
mDevice->SetPixelShader(mSolidColorPS);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t maskTexRegister;
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBPSMask);
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case RGBALAYER:
|
||||
if (aMaskType == Mask2d) {
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBAPSMask);
|
||||
} else {
|
||||
mDevice->SetVertexShader(mLayerVSMask3D);
|
||||
mDevice->SetPixelShader(mRGBAPSMask3D);
|
||||
}
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case COMPONENTLAYERPASS1:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass1PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case COMPONENTLAYERPASS2:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass2PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mYCbCrPSMask);
|
||||
maskTexRegister = 3;
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mSolidColorPSMask);
|
||||
maskTexRegister = 0;
|
||||
break;
|
||||
}
|
||||
return maskTexRegister;
|
||||
}
|
||||
|
||||
void
|
||||
DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
|
||||
{
|
||||
MaskType maskType = MaskNone;
|
||||
if (aMask) {
|
||||
maskType = aIs2D ? Mask2d : Mask3d;
|
||||
}
|
||||
uint32_t maskTexRegister = SetShaderMode(aMode, maskType);
|
||||
if (aMask) {
|
||||
// register allocations are taken from LayerManagerD3D9Shaders.h after
|
||||
// the shaders are compiled (genshaders.sh)
|
||||
if (!LoadMaskTexture(aMask, mDevice, maskTexRegister)) {
|
||||
// if we can't load the mask, fall back to unmasked rendering
|
||||
NS_WARNING("Could not load texture for mask layer.");
|
||||
SetShaderMode(aMode, MaskNone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,6 +797,13 @@ DeviceManagerD3D9::VerifyCaps()
|
||||
mHasDynamicTextures = true;
|
||||
}
|
||||
|
||||
if (HAS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP) &&
|
||||
LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL)) {
|
||||
mTextureAddressingMode = D3DTADDRESS_WRAP;
|
||||
} else {
|
||||
gfxPlatform::DisableBufferRotation();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "d3d9.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -26,7 +27,39 @@ const int CBmProjection = 4;
|
||||
const int CBvRenderTargetOffset = 8;
|
||||
const int CBvTextureCoords = 9;
|
||||
const int CBvLayerQuad = 10;
|
||||
// we don't use opacity with solid color shaders
|
||||
const int CBfLayerOpacity = 0;
|
||||
const int CBvColor = 0;
|
||||
|
||||
/**
|
||||
* This structure is used to pass rectangles to our shader constant. We can use
|
||||
* this for passing rectangular areas to SetVertexShaderConstant. In the format
|
||||
* of a 4 component float(x,y,width,height). Our vertex shader can then use
|
||||
* this to construct rectangular positions from the 0,0-1,1 quad that we source
|
||||
* it with.
|
||||
*/
|
||||
struct ShaderConstantRect
|
||||
{
|
||||
float mX, mY, mWidth, mHeight;
|
||||
|
||||
// Provide all the commonly used argument types to prevent all the local
|
||||
// casts in the code.
|
||||
ShaderConstantRect(float aX, float aY, float aWidth, float aHeight)
|
||||
: mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
|
||||
: mX((float)aX), mY((float)aY)
|
||||
, mWidth((float)aWidth), mHeight((float)aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, float aWidth, float aHeight)
|
||||
: mX((float)aX), mY((float)aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
// For easy passing to SetVertexShaderConstantF.
|
||||
operator float* () { return &mX; }
|
||||
};
|
||||
|
||||
/**
|
||||
* SwapChain class, this class manages the swap chain belonging to a
|
||||
@ -50,11 +83,14 @@ public:
|
||||
*/
|
||||
bool PrepareForRendering();
|
||||
|
||||
already_AddRefed<IDirect3DSurface9> GetBackBuffer();
|
||||
|
||||
/**
|
||||
* This function will present the selected rectangle of the swap chain to
|
||||
* its associated window.
|
||||
*/
|
||||
void Present(const nsIntRect &aRect);
|
||||
void Present();
|
||||
|
||||
private:
|
||||
friend class DeviceManagerD3D9;
|
||||
@ -83,13 +119,8 @@ class DeviceManagerD3D9 MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
DeviceManagerD3D9();
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
protected:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
NS_DECL_OWNINGTHREAD
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DeviceManagerD3D9)
|
||||
|
||||
public:
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
@ -118,6 +149,8 @@ public:
|
||||
};
|
||||
|
||||
void SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D);
|
||||
// returns the register to be used for the mask texture, if appropriate
|
||||
uint32_t SetShaderMode(ShaderMode aMode, MaskType aMaskType);
|
||||
|
||||
/**
|
||||
* Return pointer to the Nv3DVUtils instance
|
||||
@ -139,6 +172,8 @@ public:
|
||||
|
||||
int32_t GetMaxTextureSize() { return mMaxTextureSize; }
|
||||
|
||||
static uint32_t sMaskQuadRegister;
|
||||
|
||||
private:
|
||||
friend class SwapChainD3D9;
|
||||
|
||||
@ -222,6 +257,12 @@ private:
|
||||
|
||||
uint32_t mMaxTextureSize;
|
||||
|
||||
/**
|
||||
* Wrap (repeat) or clamp textures. We prefer the former so we can do buffer
|
||||
* rotation, but some older hardware doesn't support it.
|
||||
*/
|
||||
D3DTEXTUREADDRESS mTextureAddressingMode;
|
||||
|
||||
/* If this device supports dynamic textures */
|
||||
bool mHasDynamicTextures;
|
||||
|
||||
|
@ -22,36 +22,6 @@ namespace layers {
|
||||
class LayerD3D9;
|
||||
class ThebesLayerD3D9;
|
||||
|
||||
/**
|
||||
* This structure is used to pass rectangles to our shader constant. We can use
|
||||
* this for passing rectangular areas to SetVertexShaderConstant. In the format
|
||||
* of a 4 component float(x,y,width,height). Our vertex shader can then use
|
||||
* this to construct rectangular positions from the 0,0-1,1 quad that we source
|
||||
* it with.
|
||||
*/
|
||||
struct ShaderConstantRect
|
||||
{
|
||||
float mX, mY, mWidth, mHeight;
|
||||
|
||||
// Provide all the commonly used argument types to prevent all the local
|
||||
// casts in the code.
|
||||
ShaderConstantRect(float aX, float aY, float aWidth, float aHeight)
|
||||
: mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
|
||||
: mX((float)aX), mY((float)aY)
|
||||
, mWidth((float)aWidth), mHeight((float)aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, float aWidth, float aHeight)
|
||||
: mX((float)aX), mY((float)aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
// For easy passing to SetVertexShaderConstantF.
|
||||
operator float* () { return &mX; }
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the LayerManager used for Direct3D 9. For now this will render on
|
||||
* the main thread.
|
||||
|
628
gfx/layers/d3d9/TextureD3D9.cpp
Normal file
628
gfx/layers/d3d9/TextureD3D9.cpp
Normal file
@ -0,0 +1,628 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "TextureD3D9.h"
|
||||
#include "CompositorD3D9.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "Effects.h"
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
TemporaryRef<DeprecatedTextureHost>
|
||||
CreateDeprecatedTextureHostD3D9(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags)
|
||||
{
|
||||
RefPtr<DeprecatedTextureHost> result;
|
||||
if (aDescriptorType == SurfaceDescriptor::TYCbCrImage) {
|
||||
result = new DeprecatedTextureHostYCbCrD3D9();
|
||||
} else if (aDescriptorType == SurfaceDescriptor::TSurfaceDescriptorD3D9) {
|
||||
result = new DeprecatedTextureHostSystemMemD3D9();
|
||||
} else {
|
||||
result = new DeprecatedTextureHostShmemD3D9();
|
||||
}
|
||||
|
||||
result->SetFlags(aTextureFlags);
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
|
||||
CompositingRenderTargetD3D9::CompositingRenderTargetD3D9(IDirect3DTexture9* aTexture,
|
||||
SurfaceInitMode aInit,
|
||||
const gfx::IntSize& aSize)
|
||||
: mInitMode(aInit)
|
||||
, mInitialized(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CompositingRenderTargetD3D9);
|
||||
MOZ_ASSERT(aTexture);
|
||||
|
||||
mTextures[0] = aTexture;
|
||||
HRESULT hr = mTextures[0]->GetSurfaceLevel(0, getter_AddRefs(mSurface));
|
||||
NS_ASSERTION(mSurface, "Couldn't create surface for texture");
|
||||
TextureSourceD3D9::SetSize(aSize);
|
||||
}
|
||||
|
||||
CompositingRenderTargetD3D9::CompositingRenderTargetD3D9(IDirect3DSurface9* aSurface,
|
||||
SurfaceInitMode aInit,
|
||||
const gfx::IntSize& aSize)
|
||||
: mSurface(aSurface)
|
||||
, mInitMode(aInit)
|
||||
, mInitialized(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CompositingRenderTargetD3D9);
|
||||
MOZ_ASSERT(mSurface);
|
||||
TextureSourceD3D9::SetSize(aSize);
|
||||
}
|
||||
|
||||
CompositingRenderTargetD3D9::~CompositingRenderTargetD3D9()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CompositingRenderTargetD3D9);
|
||||
}
|
||||
|
||||
void
|
||||
CompositingRenderTargetD3D9::BindRenderTarget(IDirect3DDevice9* aDevice)
|
||||
{
|
||||
aDevice->SetRenderTarget(0, mSurface);
|
||||
if (!mInitialized &&
|
||||
mInitMode == INIT_MODE_CLEAR) {
|
||||
mInitialized = true;
|
||||
aDevice->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
IntSize
|
||||
CompositingRenderTargetD3D9::GetSize() const
|
||||
{
|
||||
return TextureSourceD3D9::GetSize();
|
||||
}
|
||||
|
||||
DeprecatedTextureHostD3D9::DeprecatedTextureHostD3D9()
|
||||
: mIsTiled(false)
|
||||
, mCurrentTile(0)
|
||||
, mIterating(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(DeprecatedTextureHostD3D9);
|
||||
}
|
||||
|
||||
DeprecatedTextureHostD3D9::~DeprecatedTextureHostD3D9()
|
||||
{
|
||||
MOZ_COUNT_DTOR(DeprecatedTextureHostD3D9);
|
||||
}
|
||||
|
||||
IntSize
|
||||
DeprecatedTextureHostD3D9::GetSize() const
|
||||
{
|
||||
if (mIterating) {
|
||||
gfx::IntRect rect = GetTileRect(mCurrentTile);
|
||||
return gfx::IntSize(rect.width, rect.height);
|
||||
}
|
||||
return TextureSourceD3D9::GetSize();
|
||||
}
|
||||
|
||||
nsIntRect
|
||||
DeprecatedTextureHostD3D9::GetTileRect()
|
||||
{
|
||||
IntRect rect = GetTileRect(mCurrentTile);
|
||||
return nsIntRect(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
static uint32_t GetRequiredTiles(uint32_t aSize, uint32_t aMaxSize)
|
||||
{
|
||||
uint32_t requiredTiles = aSize / aMaxSize;
|
||||
if (aSize % aMaxSize) {
|
||||
requiredTiles++;
|
||||
}
|
||||
return requiredTiles;
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureHostD3D9::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = static_cast<CompositorD3D9*>(aCompositor);
|
||||
mDevice = mCompositor ? mCompositor->device() : nullptr;
|
||||
}
|
||||
|
||||
static TemporaryRef<IDirect3DTexture9>
|
||||
DataToTexture(IDirect3DDevice9 *aDevice,
|
||||
unsigned char *aData,
|
||||
int aStride,
|
||||
const gfxIntSize &aSize,
|
||||
_D3DFORMAT aFormat,
|
||||
uint32_t aBPP)
|
||||
{
|
||||
RefPtr<IDirect3DTexture9> texture;
|
||||
nsRefPtr<IDirect3DDevice9Ex> deviceEx;
|
||||
aDevice->QueryInterface(IID_IDirect3DDevice9Ex,
|
||||
(void**)getter_AddRefs(deviceEx));
|
||||
|
||||
RefPtr<IDirect3DSurface9> surface;
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
if (deviceEx) {
|
||||
// D3D9Ex doesn't support managed textures. We could use dynamic textures
|
||||
// here but since Images are immutable that probably isn't such a great
|
||||
// idea.
|
||||
if (FAILED(aDevice->
|
||||
CreateTexture(aSize.width, aSize.height,
|
||||
1, 0, aFormat, D3DPOOL_DEFAULT,
|
||||
byRef(texture), nullptr)))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IDirect3DTexture9> tmpTexture;
|
||||
if (FAILED(aDevice->
|
||||
CreateTexture(aSize.width, aSize.height,
|
||||
1, 0, aFormat, D3DPOOL_SYSTEMMEM,
|
||||
byRef(tmpTexture), nullptr)))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tmpTexture->GetSurfaceLevel(0, byRef(surface));
|
||||
surface->LockRect(&lockedRect, NULL, 0);
|
||||
NS_ASSERTION(lockedRect.pBits, "Could not lock surface");
|
||||
} else {
|
||||
if (FAILED(aDevice->
|
||||
CreateTexture(aSize.width, aSize.height,
|
||||
1, 0, aFormat, D3DPOOL_MANAGED,
|
||||
byRef(texture), nullptr))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* lock the entire texture */
|
||||
texture->LockRect(0, &lockedRect, nullptr, 0);
|
||||
}
|
||||
|
||||
uint32_t width = aSize.width * aBPP;
|
||||
|
||||
for (int y = 0; y < aSize.height; y++) {
|
||||
memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y,
|
||||
aData + aStride * y,
|
||||
width);
|
||||
}
|
||||
|
||||
if (deviceEx) {
|
||||
surface->UnlockRect();
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
texture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
aDevice->UpdateSurface(surface, NULL, dstSurface, NULL);
|
||||
} else {
|
||||
texture->UnlockRect(0);
|
||||
}
|
||||
|
||||
return texture.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureHostShmemD3D9::UpdateImpl(const SurfaceDescriptor& aImage,
|
||||
nsIntRegion *aRegion,
|
||||
nsIntPoint *aOffset)
|
||||
{
|
||||
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TShmem ||
|
||||
aImage.type() == SurfaceDescriptor::TMemoryImage);
|
||||
MOZ_ASSERT(mCompositor, "Must have compositor to update.");
|
||||
|
||||
AutoOpenSurface openSurf(OPEN_READ_ONLY, aImage);
|
||||
|
||||
nsRefPtr<gfxImageSurface> surf = openSurf.GetAsImage();
|
||||
|
||||
gfxIntSize size = surf->GetSize();
|
||||
mSize = IntSize(size.width, size.height);
|
||||
|
||||
uint32_t bpp = 0;
|
||||
|
||||
_D3DFORMAT format = D3DFMT_A8R8G8B8;
|
||||
switch (surf->Format()) {
|
||||
case gfxImageSurface::ImageFormatRGB24:
|
||||
mFormat = FORMAT_B8G8R8X8;
|
||||
format = D3DFMT_X8R8G8B8;
|
||||
bpp = 4;
|
||||
break;
|
||||
case gfxImageSurface::ImageFormatARGB32:
|
||||
mFormat = FORMAT_B8G8R8A8;
|
||||
format = D3DFMT_A8R8G8B8;
|
||||
bpp = 4;
|
||||
break;
|
||||
case gfxImageSurface::ImageFormatA8:
|
||||
mFormat = FORMAT_A8;
|
||||
format = D3DFMT_A8;
|
||||
bpp = 1;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Bad image format");
|
||||
}
|
||||
|
||||
int32_t maxSize = mCompositor->GetMaxTextureSize();
|
||||
if (size.width <= maxSize && size.height <= maxSize) {
|
||||
mTextures[0] = DataToTexture(mDevice,
|
||||
surf->Data(), surf->Stride(),
|
||||
size, format, bpp);
|
||||
NS_ASSERTION(mTextures[0], "Could not upload texture");
|
||||
mIsTiled = false;
|
||||
} else {
|
||||
mIsTiled = true;
|
||||
uint32_t tileCount = GetRequiredTiles(size.width, maxSize) *
|
||||
GetRequiredTiles(size.height, maxSize);
|
||||
mTileTextures.resize(tileCount);
|
||||
|
||||
for (uint32_t i = 0; i < tileCount; i++) {
|
||||
IntRect tileRect = GetTileRect(i);
|
||||
unsigned char* data = surf->Data() +
|
||||
tileRect.y * surf->Stride() +
|
||||
tileRect.x * bpp;
|
||||
mTileTextures[i] = DataToTexture(mDevice,
|
||||
data,
|
||||
surf->Stride(),
|
||||
gfxIntSize(tileRect.width, tileRect.height),
|
||||
format,
|
||||
bpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IntRect
|
||||
DeprecatedTextureHostD3D9::GetTileRect(uint32_t aID) const
|
||||
{
|
||||
uint32_t maxSize = mCompositor->GetMaxTextureSize();
|
||||
uint32_t horizontalTiles = GetRequiredTiles(mSize.width, maxSize);
|
||||
uint32_t verticalTiles = GetRequiredTiles(mSize.height, maxSize);
|
||||
|
||||
uint32_t verticalTile = aID / horizontalTiles;
|
||||
uint32_t horizontalTile = aID % horizontalTiles;
|
||||
|
||||
return IntRect(horizontalTile * maxSize,
|
||||
verticalTile * maxSize,
|
||||
horizontalTile < (horizontalTiles - 1) ? maxSize : mSize.width % maxSize,
|
||||
verticalTile < (verticalTiles - 1) ? maxSize : mSize.height % maxSize);
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureHostYCbCrD3D9::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
CompositorD3D9 *d3dCompositor = static_cast<CompositorD3D9*>(aCompositor);
|
||||
mDevice = d3dCompositor ? d3dCompositor->device() : nullptr;
|
||||
}
|
||||
|
||||
IntSize
|
||||
DeprecatedTextureHostYCbCrD3D9::GetSize() const
|
||||
{
|
||||
return TextureSourceD3D9::GetSize();
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureHostYCbCrD3D9::UpdateImpl(const SurfaceDescriptor& aImage,
|
||||
nsIntRegion *aRegion,
|
||||
nsIntPoint *aOffset)
|
||||
{
|
||||
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage);
|
||||
|
||||
YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
|
||||
|
||||
gfxIntSize gfxCbCrSize = yuvDeserializer.GetCbCrSize();
|
||||
gfxIntSize size = yuvDeserializer.GetYSize();
|
||||
mSize = IntSize(size.width, size.height);
|
||||
mStereoMode = yuvDeserializer.GetStereoMode();
|
||||
|
||||
mTextures[0] = DataToTexture(mDevice,
|
||||
yuvDeserializer.GetYData(),
|
||||
yuvDeserializer.GetYStride(),
|
||||
size,
|
||||
D3DFMT_L8, 1);
|
||||
mTextures[1] = DataToTexture(mDevice,
|
||||
yuvDeserializer.GetCbData(),
|
||||
yuvDeserializer.GetCbCrStride(),
|
||||
gfxCbCrSize,
|
||||
D3DFMT_L8, 1);
|
||||
mTextures[2] = DataToTexture(mDevice,
|
||||
yuvDeserializer.GetCrData(),
|
||||
yuvDeserializer.GetCbCrStride(),
|
||||
gfxCbCrSize,
|
||||
D3DFMT_L8, 1);
|
||||
}
|
||||
|
||||
// aTexture should be in SYSTEMMEM, returns a texture in the default
|
||||
// pool (that is, in video memory).
|
||||
static TemporaryRef<IDirect3DTexture9>
|
||||
TextureToTexture(IDirect3DDevice9* aDevice,
|
||||
IDirect3DTexture9* aTexture,
|
||||
const IntSize& aSize,
|
||||
_D3DFORMAT aFormat)
|
||||
{
|
||||
RefPtr<IDirect3DTexture9> texture;
|
||||
if (FAILED(aDevice->
|
||||
CreateTexture(aSize.width, aSize.height,
|
||||
1, 0, aFormat, D3DPOOL_DEFAULT,
|
||||
byRef(texture), nullptr))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HRESULT hr = aDevice->UpdateTexture(aTexture, texture);
|
||||
if (FAILED(hr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return texture.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureHostSystemMemD3D9::UpdateImpl(const SurfaceDescriptor& aImage,
|
||||
nsIntRegion *aRegion,
|
||||
nsIntPoint *aOffset)
|
||||
{
|
||||
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorD3D9);
|
||||
MOZ_ASSERT(mCompositor, "Must have compositor to update.");
|
||||
|
||||
IDirect3DTexture9* texture =
|
||||
reinterpret_cast<IDirect3DTexture9*>(aImage.get_SurfaceDescriptorD3D9().texture());
|
||||
|
||||
if (!texture) {
|
||||
mTextures[0] = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
texture->GetLevelDesc(0, &desc);
|
||||
mSize.width = desc.Width;
|
||||
mSize.height = desc.Height;
|
||||
|
||||
_D3DFORMAT format = desc.Format;
|
||||
uint32_t bpp = 0;
|
||||
switch (format) {
|
||||
case D3DFMT_X8R8G8B8:
|
||||
mFormat = FORMAT_B8G8R8X8;
|
||||
bpp = 4;
|
||||
break;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
mFormat = FORMAT_B8G8R8A8;
|
||||
bpp = 4;
|
||||
break;
|
||||
case D3DFMT_A8:
|
||||
mFormat = FORMAT_A8;
|
||||
bpp = 1;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Bad image format");
|
||||
}
|
||||
|
||||
int32_t maxSize = mCompositor->GetMaxTextureSize();
|
||||
if (mSize.width <= maxSize && mSize.height <= maxSize) {
|
||||
mIsTiled = false;
|
||||
|
||||
mTextures[0] = TextureToTexture(mDevice, texture, mSize, format);
|
||||
NS_ASSERTION(mTextures[0], "Could not upload texture");
|
||||
} else {
|
||||
mIsTiled = true;
|
||||
|
||||
uint32_t tileCount = GetRequiredTiles(mSize.width, maxSize) *
|
||||
GetRequiredTiles(mSize.height, maxSize);
|
||||
mTileTextures.resize(tileCount);
|
||||
|
||||
for (uint32_t i = 0; i < tileCount; i++) {
|
||||
IntRect tileRect = GetTileRect(i);
|
||||
RECT d3dTileRect;
|
||||
d3dTileRect.left = tileRect.x;
|
||||
d3dTileRect.top = tileRect.y;
|
||||
d3dTileRect.right = tileRect.XMost();
|
||||
d3dTileRect.bottom = tileRect.YMost();
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
texture->LockRect(0, &lockedRect, &d3dTileRect, 0);
|
||||
mTileTextures[i] = DataToTexture(mDevice,
|
||||
reinterpret_cast<unsigned char*>(lockedRect.pBits),
|
||||
lockedRect.Pitch,
|
||||
gfxIntSize(tileRect.width, tileRect.height),
|
||||
format,
|
||||
bpp);
|
||||
texture->UnlockRect(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeprecatedTextureClientD3D9::DeprecatedTextureClientD3D9(CompositableForwarder* aCompositableForwarder,
|
||||
const TextureInfo& aTextureInfo)
|
||||
: DeprecatedTextureClient(aCompositableForwarder, aTextureInfo)
|
||||
, mDC(nullptr)
|
||||
, mTextureLocked(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(DeprecatedTextureClientD3D9);
|
||||
}
|
||||
|
||||
DeprecatedTextureClientD3D9::~DeprecatedTextureClientD3D9()
|
||||
{
|
||||
MOZ_COUNT_DTOR(DeprecatedTextureClientD3D9);
|
||||
Unlock();
|
||||
mDescriptor = SurfaceDescriptor();
|
||||
|
||||
ClearDT();
|
||||
}
|
||||
|
||||
bool
|
||||
DeprecatedTextureClientD3D9::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType)
|
||||
{
|
||||
if (mTexture) {
|
||||
D3DSURFACE_DESC desc;
|
||||
mTexture->GetLevelDesc(0, &desc);
|
||||
|
||||
if (desc.Width == aSize.width &&
|
||||
desc.Height == aSize.height) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Unlock();
|
||||
mD3D9Surface = nullptr;
|
||||
mTexture = nullptr;
|
||||
}
|
||||
|
||||
mSize = aSize;
|
||||
|
||||
_D3DFORMAT format = D3DFMT_A8R8G8B8;
|
||||
switch (aType) {
|
||||
case gfxASurface::CONTENT_COLOR:
|
||||
format = D3DFMT_X8R8G8B8;
|
||||
mIsOpaque = true;
|
||||
break;
|
||||
case gfxASurface::CONTENT_COLOR_ALPHA:
|
||||
format = D3DFMT_A8R8G8B8;
|
||||
mIsOpaque = false;
|
||||
break;
|
||||
case gfxASurface::CONTENT_ALPHA:
|
||||
format = D3DFMT_A8;
|
||||
mIsOpaque = true;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Bad image type");
|
||||
}
|
||||
|
||||
IDirect3DDevice9 *device = gfxWindowsPlatform::GetPlatform()->GetD3D9Device();
|
||||
if (!device ||
|
||||
FAILED(device->
|
||||
CreateTexture(aSize.width, aSize.height,
|
||||
1, 0, format, D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(mTexture), nullptr)))
|
||||
{
|
||||
NS_WARNING("Could not create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mTexture);
|
||||
mDescriptor = SurfaceDescriptorD3D9(reinterpret_cast<uintptr_t>(mTexture.get()));
|
||||
|
||||
if (!mIsOpaque) {
|
||||
nsRefPtr<gfxASurface> surface = LockSurface();
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surface);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetColor(gfxRGBA(0.0, 0.0, 0.0, 0.0));
|
||||
ctx->Paint();
|
||||
Unlock();
|
||||
}
|
||||
|
||||
mContentType = aType;
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
DeprecatedTextureClientD3D9::LockSurface()
|
||||
{
|
||||
if (mSurface) {
|
||||
return mSurface.get();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mTexture, "Cannot lock surface without a texture to lock");
|
||||
|
||||
if (mIsOpaque) {
|
||||
MOZ_ASSERT(!mTextureLocked, "Shouldn't lock texture and have a surface");
|
||||
if (!mD3D9Surface) {
|
||||
HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(mD3D9Surface));
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to get texture surface level.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mDC) {
|
||||
HRESULT hr = mD3D9Surface->GetDC(&mDC);
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to get device context for texture surface.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(mDC, "We need a DC here");
|
||||
mSurface = new gfxWindowsSurface(mDC);
|
||||
} else {
|
||||
// d3d9 SYSTEMMEM surfaces do not support GDI with an alpha channel
|
||||
MOZ_ASSERT(!mD3D9Surface && !mDC, "Shouldn't lock texture and have a surface");
|
||||
if (!mTextureLocked) {
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
mTexture->LockRect(0, &lockedRect, nullptr, 0);
|
||||
mTextureLocked = true;
|
||||
|
||||
mSurface = new gfxImageSurface(reinterpret_cast<unsigned char*>(lockedRect.pBits),
|
||||
gfxIntSize(mSize.width, mSize.height),
|
||||
lockedRect.Pitch,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(mSurface, "should have a surface one way or the other");
|
||||
return mSurface.get();
|
||||
}
|
||||
|
||||
DrawTarget*
|
||||
DeprecatedTextureClientD3D9::LockDrawTarget()
|
||||
{
|
||||
if (!mDrawTarget) {
|
||||
mDrawTarget =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(LockSurface(), mSize);
|
||||
}
|
||||
|
||||
return mDrawTarget.get();
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureClientD3D9::Unlock()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->Flush();
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
if (mTextureLocked) {
|
||||
MOZ_ASSERT(!mD3D9Surface && !mDC, "Shouldn't lock texture and have a surface");
|
||||
mTexture->UnlockRect(0);
|
||||
mTextureLocked = false;
|
||||
} else if (mDC) {
|
||||
MOZ_ASSERT(mD3D9Surface, "we need a D3D9Surface to release our DC");
|
||||
MOZ_ASSERT(!mTextureLocked, "Shouldn't lock texture and have a surface");
|
||||
mD3D9Surface->ReleaseDC(mDC);
|
||||
mDC = nullptr;
|
||||
}
|
||||
|
||||
if (mSurface) {
|
||||
mSurface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureClientD3D9::SetDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
if (aDescriptor.type() == SurfaceDescriptor::Tnull_t) {
|
||||
EnsureAllocated(mSize, mContentType);
|
||||
return;
|
||||
}
|
||||
|
||||
mDescriptor = aDescriptor;
|
||||
mSurface = nullptr;
|
||||
ClearDT();
|
||||
|
||||
if (aDescriptor.type() == SurfaceDescriptor::T__None) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorD3D9);
|
||||
Unlock();
|
||||
mD3D9Surface = nullptr;
|
||||
mTexture = reinterpret_cast<IDirect3DTexture9*>(
|
||||
mDescriptor.get_SurfaceDescriptorD3D9().texture());
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedTextureClientD3D9::ClearDT()
|
||||
{
|
||||
// Perhaps this should be debug only.
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
260
gfx/layers/d3d9/TextureD3D9.h
Normal file
260
gfx/layers/d3d9/TextureD3D9.h
Normal file
@ -0,0 +1,260 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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_TEXTURED3D9_H
|
||||
#define MOZILLA_GFX_TEXTURED3D9_H
|
||||
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "d3d9.h"
|
||||
#include <vector>
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CompositorD3D9;
|
||||
|
||||
class TextureSourceD3D9
|
||||
{
|
||||
public:
|
||||
virtual IDirect3DTexture9* GetD3D9Texture() { return mTextures[0]; }
|
||||
virtual bool IsYCbCrSource() const { return false; }
|
||||
|
||||
struct YCbCrTextures
|
||||
{
|
||||
IDirect3DTexture9 *mY;
|
||||
IDirect3DTexture9 *mCb;
|
||||
IDirect3DTexture9 *mCr;
|
||||
StereoMode mStereoMode;
|
||||
};
|
||||
|
||||
virtual YCbCrTextures GetYCbCrTextures() {
|
||||
YCbCrTextures textures = { mTextures[0],
|
||||
mTextures[1],
|
||||
mTextures[2],
|
||||
mStereoMode };
|
||||
return textures;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual gfx::IntSize GetSize() const { return mSize; }
|
||||
void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
|
||||
|
||||
gfx::IntSize mSize;
|
||||
StereoMode mStereoMode;
|
||||
RefPtr<IDirect3DTexture9> mTextures[3];
|
||||
};
|
||||
|
||||
class CompositingRenderTargetD3D9 : public CompositingRenderTarget,
|
||||
public TextureSourceD3D9
|
||||
{
|
||||
public:
|
||||
CompositingRenderTargetD3D9(IDirect3DTexture9* aTexture,
|
||||
SurfaceInitMode aInit,
|
||||
const gfx::IntSize& aSize);
|
||||
// use for rendering to the main window, cannot be rendered as a texture
|
||||
CompositingRenderTargetD3D9(IDirect3DSurface9* aSurface,
|
||||
SurfaceInitMode aInit,
|
||||
const gfx::IntSize& aSize);
|
||||
~CompositingRenderTargetD3D9();
|
||||
|
||||
virtual TextureSourceD3D9* AsSourceD3D9() MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(mTextures[0],
|
||||
"No texture, can't be indirectly rendered. Is this the screen backbuffer?");
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
void BindRenderTarget(IDirect3DDevice9* aDevice);
|
||||
|
||||
IDirect3DSurface9* GetD3D9Surface() const { return mSurface; }
|
||||
|
||||
private:
|
||||
friend class CompositorD3D9;
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> mSurface;
|
||||
SurfaceInitMode mInitMode;
|
||||
bool mInitialized;
|
||||
};
|
||||
|
||||
// Shared functionality for non-YCbCr texture hosts
|
||||
class DeprecatedTextureHostD3D9 : public DeprecatedTextureHost
|
||||
, public TextureSourceD3D9
|
||||
, public TileIterator
|
||||
{
|
||||
public:
|
||||
DeprecatedTextureHostD3D9();
|
||||
virtual ~DeprecatedTextureHostD3D9();
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSourceD3D9* AsSourceD3D9() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual IDirect3DTexture9 *GetD3D9Texture() MOZ_OVERRIDE {
|
||||
return mIsTiled ? mTileTextures[mCurrentTile].get()
|
||||
: TextureSourceD3D9::GetD3D9Texture();
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
virtual LayerRenderState GetRenderState() { return LayerRenderState(); }
|
||||
|
||||
virtual bool Lock() MOZ_OVERRIDE { return true; }
|
||||
|
||||
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
|
||||
{
|
||||
return nullptr; // TODO: cf bug 872568
|
||||
}
|
||||
|
||||
virtual void BeginTileIteration() MOZ_OVERRIDE
|
||||
{
|
||||
mIterating = true;
|
||||
mCurrentTile = 0;
|
||||
}
|
||||
virtual void EndTileIteration() MOZ_OVERRIDE
|
||||
{
|
||||
mIterating = false;
|
||||
}
|
||||
virtual nsIntRect GetTileRect() MOZ_OVERRIDE;
|
||||
virtual size_t GetTileCount() MOZ_OVERRIDE { return mTileTextures.size(); }
|
||||
virtual bool NextTile() MOZ_OVERRIDE
|
||||
{
|
||||
return (++mCurrentTile < mTileTextures.size());
|
||||
}
|
||||
|
||||
virtual TileIterator* AsTileIterator() MOZ_OVERRIDE
|
||||
{
|
||||
return mIsTiled ? this : nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
gfx::IntRect GetTileRect(uint32_t aID) const;
|
||||
|
||||
RefPtr<IDirect3DDevice9> mDevice;
|
||||
RefPtr<CompositorD3D9> mCompositor;
|
||||
bool mIsTiled;
|
||||
std::vector< RefPtr<IDirect3DTexture9> > mTileTextures;
|
||||
uint32_t mCurrentTile;
|
||||
bool mIterating;
|
||||
};
|
||||
|
||||
class DeprecatedTextureHostShmemD3D9 : public DeprecatedTextureHostD3D9
|
||||
{
|
||||
public:
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() { return "DeprecatedTextureHostShmemD3D9"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
|
||||
nsIntRegion* aRegion,
|
||||
nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
class DeprecatedTextureHostSystemMemD3D9 : public DeprecatedTextureHostD3D9
|
||||
{
|
||||
public:
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() { return "DeprecatedTextureHostSystemMemD3D9"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
|
||||
nsIntRegion* aRegion,
|
||||
nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
};
|
||||
|
||||
class DeprecatedTextureHostYCbCrD3D9 : public DeprecatedTextureHost
|
||||
, public TextureSourceD3D9
|
||||
{
|
||||
public:
|
||||
DeprecatedTextureHostYCbCrD3D9()
|
||||
: mDevice(nullptr)
|
||||
{
|
||||
mFormat = gfx::FORMAT_YUV;
|
||||
}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSourceD3D9* AsSourceD3D9() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsYCbCrSource() const MOZ_OVERRIDE { return true; }
|
||||
|
||||
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
|
||||
{
|
||||
return nullptr; // TODO: cf bug 872568
|
||||
}
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() MOZ_OVERRIDE
|
||||
{
|
||||
return "TextureImageDeprecatedTextureHostD3D11";
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
|
||||
nsIntRegion* aRegion,
|
||||
nsIntPoint* aOffset = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
RefPtr<IDirect3DDevice9> mDevice;
|
||||
};
|
||||
|
||||
// If we want to use d3d9 textures for transport, use this class.
|
||||
// If we are using shmem, then use DeprecatedTextureClientShmem with DeprecatedTextureHostShmemD3D9
|
||||
// Since we pass a raw pointer, you should not use this texture client for
|
||||
// multi-process compositing.
|
||||
class DeprecatedTextureClientD3D9 : public DeprecatedTextureClient
|
||||
{
|
||||
public:
|
||||
DeprecatedTextureClientD3D9(CompositableForwarder* aCompositableForwarder,
|
||||
const TextureInfo& aTextureInfo);
|
||||
virtual ~DeprecatedTextureClientD3D9();
|
||||
|
||||
virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE
|
||||
{
|
||||
return aType == TEXTURE_CONTENT;
|
||||
}
|
||||
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual gfxASurface* LockSurface() MOZ_OVERRIDE;
|
||||
virtual gfx::DrawTarget* LockDrawTarget() MOZ_OVERRIDE;
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
virtual gfxASurface::gfxContentType GetContentType() MOZ_OVERRIDE
|
||||
{
|
||||
return mContentType;
|
||||
}
|
||||
|
||||
private:
|
||||
void ClearDT();
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsRefPtr<IDirect3DSurface9> mD3D9Surface;
|
||||
HDC mDC;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfxContentType mContentType;
|
||||
bool mTextureLocked;
|
||||
bool mIsOpaque;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_GFX_TEXTURED3D9_H */
|
@ -41,6 +41,7 @@ public:
|
||||
typedef gfxASurface::gfxContentType gfxContentType;
|
||||
|
||||
CompositableForwarder()
|
||||
: mMultiProcess(false)
|
||||
{}
|
||||
|
||||
/**
|
||||
@ -207,8 +208,14 @@ public:
|
||||
return mTextureFactoryIdentifier.mSupportsPartialUploads;
|
||||
}
|
||||
|
||||
bool ForwardsToDifferentProcess() const
|
||||
{
|
||||
return mMultiProcess;
|
||||
}
|
||||
|
||||
protected:
|
||||
TextureFactoryIdentifier mTextureFactoryIdentifier;
|
||||
bool mMultiProcess;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -73,7 +73,8 @@ CompositorChild::Get()
|
||||
PLayerTransactionChild*
|
||||
CompositorChild::AllocPLayerTransactionChild(const LayersBackend& aBackendHint,
|
||||
const uint64_t& aId,
|
||||
TextureFactoryIdentifier*)
|
||||
TextureFactoryIdentifier*,
|
||||
bool*)
|
||||
{
|
||||
return new LayerTransactionChild();
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ protected:
|
||||
virtual PLayerTransactionChild*
|
||||
AllocPLayerTransactionChild(const LayersBackend& aBackendHint,
|
||||
const uint64_t& aId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier) MOZ_OVERRIDE;
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
bool* aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool DeallocPLayerTransactionChild(PLayerTransactionChild *aChild) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "mozilla/layers/BasicCompositor.h"
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/layers/CompositorD3D11.h"
|
||||
#include "mozilla/layers/CompositorD3D9.h"
|
||||
#endif
|
||||
#include "LayerTransactionParent.h"
|
||||
#include "nsIWidget.h"
|
||||
@ -423,16 +424,13 @@ CompositorParent::ScheduleTask(CancelableTask* task, int time)
|
||||
void
|
||||
CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint)
|
||||
{
|
||||
if (mApzcTreeManager) {
|
||||
if (mApzcTreeManager &&
|
||||
mLayerManager &&
|
||||
mLayerManager->GetRoot()) {
|
||||
AutoResolveRefLayers resolve(mCompositionManager);
|
||||
mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId);
|
||||
}
|
||||
|
||||
if (mLayerManager) {
|
||||
LayerManagerComposite* managerComposite = mLayerManager->AsLayerManagerComposite();
|
||||
if (managerComposite) {
|
||||
managerComposite->NotifyShadowTreeTransaction();
|
||||
}
|
||||
mLayerManager->AsLayerManagerComposite()->NotifyShadowTreeTransaction();
|
||||
}
|
||||
ScheduleComposition();
|
||||
}
|
||||
@ -603,7 +601,8 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
|
||||
PLayerTransactionParent*
|
||||
CompositorParent::AllocPLayerTransactionParent(const LayersBackend& aBackendHint,
|
||||
const uint64_t& aId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier)
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
bool *aSuccess)
|
||||
{
|
||||
MOZ_ASSERT(aId == 0);
|
||||
|
||||
@ -625,23 +624,29 @@ CompositorParent::AllocPLayerTransactionParent(const LayersBackend& aBackendHint
|
||||
} else if (aBackendHint == mozilla::layers::LAYERS_D3D11) {
|
||||
mLayerManager =
|
||||
new LayerManagerComposite(new CompositorD3D11(mWidget));
|
||||
} else if (aBackendHint == mozilla::layers::LAYERS_D3D9) {
|
||||
mLayerManager =
|
||||
new LayerManagerComposite(new CompositorD3D9(mWidget));
|
||||
#endif
|
||||
} else {
|
||||
NS_ERROR("Unsupported backend selected for Async Compositor");
|
||||
return nullptr;
|
||||
NS_WARNING("Unsupported backend selected for Async Compositor");
|
||||
*aSuccess = false;
|
||||
return new LayerTransactionParent(nullptr, this, 0);
|
||||
}
|
||||
|
||||
mWidget = nullptr;
|
||||
mLayerManager->SetCompositorID(mCompositorID);
|
||||
|
||||
if (!mLayerManager->Initialize()) {
|
||||
NS_ERROR("Failed to init Compositor");
|
||||
return nullptr;
|
||||
NS_WARNING("Failed to init Compositor");
|
||||
*aSuccess = false;
|
||||
return new LayerTransactionParent(nullptr, this, 0);
|
||||
}
|
||||
|
||||
mCompositionManager = new AsyncCompositionManager(mLayerManager);
|
||||
|
||||
*aTextureFactoryIdentifier = mLayerManager->GetTextureFactoryIdentifier();
|
||||
*aSuccess = true;
|
||||
return new LayerTransactionParent(mLayerManager, this, 0);
|
||||
}
|
||||
|
||||
@ -831,7 +836,8 @@ public:
|
||||
virtual PLayerTransactionParent*
|
||||
AllocPLayerTransactionParent(const LayersBackend& aBackendType,
|
||||
const uint64_t& aId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier) MOZ_OVERRIDE;
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
bool *aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) MOZ_OVERRIDE;
|
||||
|
||||
@ -912,17 +918,22 @@ CrossProcessCompositorParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
PLayerTransactionParent*
|
||||
CrossProcessCompositorParent::AllocPLayerTransactionParent(const LayersBackend& aBackendType,
|
||||
const uint64_t& aId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier)
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
bool *aSuccess)
|
||||
{
|
||||
MOZ_ASSERT(aId != 0);
|
||||
|
||||
if (sIndirectLayerTrees[aId].mParent) {
|
||||
LayerManagerComposite* lm = sIndirectLayerTrees[aId].mParent->GetLayerManager();
|
||||
*aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
|
||||
*aSuccess = true;
|
||||
return new LayerTransactionParent(lm, this, aId);
|
||||
}
|
||||
|
||||
NS_WARNING("Created child without a matching parent?");
|
||||
// XXX: should be false, but that causes us to fail some tests on Mac w/ OMTC.
|
||||
// Bug 900745. change *aSuccess to false to see test failures.
|
||||
*aSuccess = true;
|
||||
return new LayerTransactionParent(nullptr, this, aId);
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,8 @@ protected:
|
||||
virtual PLayerTransactionParent*
|
||||
AllocPLayerTransactionParent(const LayersBackend& aBackendHint,
|
||||
const uint64_t& aId,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier);
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
bool* aSuccess);
|
||||
virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers);
|
||||
virtual void ScheduleTask(CancelableTask*, int);
|
||||
virtual void Composite();
|
||||
|
@ -90,7 +90,10 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfxIntSize& aSize,
|
||||
gfxImageFormat format =
|
||||
gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent);
|
||||
int32_t stride = gfxASurface::FormatStrideForWidth(format, aSize.width);
|
||||
uint8_t *data = new uint8_t[stride * aSize.height];
|
||||
uint8_t *data = new (std::nothrow) uint8_t[stride * aSize.height];
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
#ifdef XP_MACOSX
|
||||
// Workaround a bug in Quartz where drawing an a8 surface to another a8
|
||||
// surface with OPERATOR_SOURCE still requires the destination to be clear.
|
||||
@ -133,6 +136,7 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface)
|
||||
case SurfaceDescriptor::TRGBImage:
|
||||
DeallocShmem(aSurface->get_RGBImage().data());
|
||||
break;
|
||||
case SurfaceDescriptor::TSurfaceDescriptorD3D9:
|
||||
case SurfaceDescriptor::TSurfaceDescriptorD3D10:
|
||||
break;
|
||||
case SurfaceDescriptor::TMemoryImage:
|
||||
|
@ -36,6 +36,11 @@ union MaybeMagicGrallocBufferHandle {
|
||||
null_t;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorD3D9 {
|
||||
// IDirect3DTexture9*
|
||||
uintptr_t texture;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorD3D10 {
|
||||
WindowsHandle handle;
|
||||
bool hasAlpha;
|
||||
@ -124,6 +129,7 @@ struct SurfaceDescriptorShmem {
|
||||
union SurfaceDescriptor {
|
||||
SurfaceDescriptorShmem;
|
||||
SurfaceDescriptorMemory;
|
||||
SurfaceDescriptorD3D9;
|
||||
SurfaceDescriptorD3D10;
|
||||
SurfaceDescriptorX11;
|
||||
SharedTextureDescriptor;
|
||||
|
@ -60,7 +60,7 @@ parent:
|
||||
sync FlushRendering();
|
||||
|
||||
sync PLayerTransaction(LayersBackend layersBackendHint, uint64_t id)
|
||||
returns (TextureFactoryIdentifier textureFactoryIdentifier);
|
||||
returns (TextureFactoryIdentifier textureFactoryIdentifier, bool success);
|
||||
};
|
||||
|
||||
} // layers
|
||||
|
@ -161,6 +161,7 @@ void
|
||||
CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
|
||||
{
|
||||
mTextureFactoryIdentifier = aIdentifier;
|
||||
mMultiProcess = aIdentifier.mParentProcessId != XRE_GetProcessType();
|
||||
}
|
||||
|
||||
ShadowLayerForwarder::ShadowLayerForwarder()
|
||||
|
@ -119,7 +119,8 @@ SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
|
||||
mSize = aData.mPicSize;
|
||||
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
@ -153,7 +154,8 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrImage::Data& aData)
|
||||
|
||||
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
MOZ_ASSERT(serializer.IsValid());
|
||||
|
||||
aData.mYChannel = serializer.GetYData();
|
||||
@ -239,7 +241,8 @@ DeprecatedSharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
|
||||
mSize = aData.mPicSize;
|
||||
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
@ -269,7 +272,8 @@ DeprecatedSharedPlanarYCbCrImage::Allocate(PlanarYCbCrImage::Data& aData)
|
||||
|
||||
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
if (!serializer.IsValid() || mShmem.Size<uint8_t>() < size) {
|
||||
mSurfaceAllocator->DeallocShmem(mShmem);
|
||||
return false;
|
||||
|
@ -52,7 +52,13 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
'd3d9/DeviceManagerD3D9.h',
|
||||
'd3d9/LayerManagerD3D9.h',
|
||||
]
|
||||
EXPORTS.mozilla.layers += [
|
||||
'CompositorD3D9.h',
|
||||
'TextureD3D9.h',
|
||||
]
|
||||
CPP_SOURCES += [
|
||||
'CompositorD3D9.cpp',
|
||||
'TextureD3D9.cpp',
|
||||
'LayerManagerD3D9.cpp',
|
||||
'ThebesLayerD3D9.cpp',
|
||||
'ContainerLayerD3D9.cpp',
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
|
||||
{
|
||||
return TextureFactoryIdentifier(LAYERS_OPENGL,
|
||||
XRE_GetProcessType(),
|
||||
GetMaxTextureSize(),
|
||||
mFBOTextureTarget == LOCAL_GL_TEXTURE_2D,
|
||||
SupportsPartialTextureUpdate());
|
||||
|
@ -78,11 +78,12 @@ DeprecatedTextureClientSharedOGL::ReleaseResources()
|
||||
// care of this for us though.
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientSharedOGL::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aContentType)
|
||||
{
|
||||
mSize = aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
~DeprecatedTextureClientSharedOGL() { ReleaseResources(); }
|
||||
|
||||
virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE { return aType == TEXTURE_SHARED_GL; }
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType);
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType);
|
||||
virtual void ReleaseResources();
|
||||
virtual gfxASurface::gfxContentType GetContentType() MOZ_OVERRIDE { return gfxASurface::CONTENT_COLOR_ALPHA; }
|
||||
|
||||
@ -88,7 +88,7 @@ public:
|
||||
~DeprecatedTextureClientStreamOGL() { ReleaseResources(); }
|
||||
|
||||
virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE { return aType == TEXTURE_STREAM_GL; }
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) { }
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) { return true; }
|
||||
virtual void ReleaseResources() { mDescriptor = SurfaceDescriptor(); }
|
||||
virtual gfxASurface::gfxContentType GetContentType() MOZ_OVERRIDE { return gfxASurface::CONTENT_COLOR_ALPHA; }
|
||||
};
|
||||
|
@ -73,11 +73,9 @@ gfxCachedTempSurface::Get(gfxASurface::gfxContentType aContentType,
|
||||
if (mSurface) {
|
||||
/* Verify the current buffer is valid for this purpose */
|
||||
if (mSize.width < aRect.width || mSize.height < aRect.height
|
||||
|| mSurface->GetContentType() != aContentType) {
|
||||
|| mSurface->GetContentType() != aContentType
|
||||
|| mType != aSimilarTo->GetType()) {
|
||||
mSurface = nullptr;
|
||||
} else {
|
||||
NS_ASSERTION(mType == aSimilarTo->GetType(),
|
||||
"Unexpected surface type change");
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,9 +87,7 @@ gfxCachedTempSurface::Get(gfxASurface::gfxContentType aContentType,
|
||||
return nullptr;
|
||||
|
||||
cleared = true;
|
||||
#ifdef DEBUG
|
||||
mType = aSimilarTo->GetType();
|
||||
#endif
|
||||
}
|
||||
mSurface->SetDeviceOffset(-aRect.TopLeft());
|
||||
|
||||
|
@ -33,10 +33,9 @@ public:
|
||||
* When |aContentType| differs in different invocations this is handled
|
||||
* appropriately, creating a new surface if necessary.
|
||||
*
|
||||
* |aSimilarTo| should be of the same gfxSurfaceType in each invocation.
|
||||
* Because the cached surface may have been created during a previous
|
||||
* invocation, this will not be efficient if the new |aSimilarTo| has a
|
||||
* different format.
|
||||
* different format, size, or gfxSurfaceType.
|
||||
*/
|
||||
already_AddRefed<gfxContext> Get(gfxASurface::gfxContentType aContentType,
|
||||
const gfxRect& aRect,
|
||||
@ -52,9 +51,7 @@ private:
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
gfxIntSize mSize;
|
||||
nsExpirationState mExpirationState;
|
||||
#ifdef DEBUG
|
||||
gfxASurface::gfxSurfaceType mType;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* GFX_CACHED_TEMP_SURFACE_H */
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
#include "nsIGfxInfo.h"
|
||||
|
||||
@ -86,6 +87,8 @@ using namespace mozilla::layers;
|
||||
gfxPlatform *gPlatform = nullptr;
|
||||
static bool gEverInitialized = false;
|
||||
|
||||
static Mutex* gGfxPlatformPrefsLock = nullptr;
|
||||
|
||||
// These two may point to the same profile
|
||||
static qcms_profile *gCMSOutputProfile = nullptr;
|
||||
static qcms_profile *gCMSsRGBProfile = nullptr;
|
||||
@ -313,6 +316,8 @@ gfxPlatform::Init()
|
||||
sCmapDataLog = PR_NewLogModule("cmapdata");;
|
||||
#endif
|
||||
|
||||
gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
|
||||
|
||||
/* Initialize the GfxInfo service.
|
||||
* Note: we can't call functions on GfxInfo that depend
|
||||
* on gPlatform until after it has been initialized
|
||||
@ -475,6 +480,8 @@ gfxPlatform::Shutdown()
|
||||
|
||||
CompositorParent::ShutDown();
|
||||
|
||||
delete gGfxPlatformPrefsLock;
|
||||
|
||||
delete gPlatform;
|
||||
gPlatform = nullptr;
|
||||
}
|
||||
@ -1856,11 +1863,15 @@ static bool sPrefLayersAccelerationForceEnabled = false;
|
||||
static bool sPrefLayersAccelerationDisabled = false;
|
||||
static bool sPrefLayersPreferOpenGL = false;
|
||||
static bool sPrefLayersPreferD3D9 = false;
|
||||
static bool sLayersSupportsD3D9 = true;
|
||||
static int sPrefLayoutFrameRate = -1;
|
||||
static bool sBufferRotationEnabled = false;
|
||||
|
||||
void InitLayersAccelerationPrefs()
|
||||
static bool sLayersAccelerationPrefsInitialized = false;
|
||||
|
||||
void
|
||||
InitLayersAccelerationPrefs()
|
||||
{
|
||||
static bool sLayersAccelerationPrefsInitialized = false;
|
||||
if (!sLayersAccelerationPrefsInitialized)
|
||||
{
|
||||
sPrefLayersOffMainThreadCompositionEnabled = Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
|
||||
@ -1871,12 +1882,24 @@ void InitLayersAccelerationPrefs()
|
||||
sPrefLayersPreferOpenGL = Preferences::GetBool("layers.prefer-opengl", false);
|
||||
sPrefLayersPreferD3D9 = Preferences::GetBool("layers.prefer-d3d9", false);
|
||||
sPrefLayoutFrameRate = Preferences::GetInt("layout.frame_rate", -1);
|
||||
sBufferRotationEnabled = Preferences::GetBool("layers.bufferrotation.enabled", true);
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
if (gfxInfo) {
|
||||
int32_t status;
|
||||
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, &status))) {
|
||||
if (status != nsIGfxInfo::FEATURE_NO_INFO && !sPrefLayersAccelerationForceEnabled) {
|
||||
sLayersSupportsD3D9 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sLayersAccelerationPrefsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersOffMainThreadCompositionEnabled()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersOffMainThreadCompositionEnabled()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersOffMainThreadCompositionEnabled ||
|
||||
@ -1884,13 +1907,15 @@ bool gfxPlatform::GetPrefLayersOffMainThreadCompositionEnabled()
|
||||
sPrefLayersOffMainThreadCompositionTestingEnabled;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersOffMainThreadCompositionForceEnabled()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersOffMainThreadCompositionForceEnabled()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersOffMainThreadCompositionForceEnabled;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersAccelerationForceEnabled()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersAccelerationForceEnabled()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersAccelerationForceEnabled;
|
||||
@ -1903,20 +1928,49 @@ gfxPlatform::GetPrefLayersAccelerationDisabled()
|
||||
return sPrefLayersAccelerationDisabled;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersPreferOpenGL()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersPreferOpenGL()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersPreferOpenGL;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersPreferD3D9()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersPreferD3D9()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersPreferD3D9;
|
||||
}
|
||||
|
||||
int gfxPlatform::GetPrefLayoutFrameRate()
|
||||
bool
|
||||
gfxPlatform::CanUseDirect3D9()
|
||||
{
|
||||
// this function is called from the compositor thread, so it is not
|
||||
// safe to init the prefs etc. from here.
|
||||
MOZ_ASSERT(sLayersAccelerationPrefsInitialized);
|
||||
return sLayersSupportsD3D9;
|
||||
}
|
||||
|
||||
int
|
||||
gfxPlatform::GetPrefLayoutFrameRate()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayoutFrameRate;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatform::BufferRotationEnabled()
|
||||
{
|
||||
MutexAutoLock autoLock(*gGfxPlatformPrefsLock);
|
||||
|
||||
InitLayersAccelerationPrefs();
|
||||
return sBufferRotationEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::DisableBufferRotation()
|
||||
{
|
||||
MutexAutoLock autoLock(*gGfxPlatformPrefsLock);
|
||||
|
||||
sBufferRotationEnabled = false;
|
||||
}
|
||||
|
@ -471,8 +471,14 @@ public:
|
||||
static bool GetPrefLayersAccelerationDisabled();
|
||||
static bool GetPrefLayersPreferOpenGL();
|
||||
static bool GetPrefLayersPreferD3D9();
|
||||
static bool CanUseDirect3D9();
|
||||
static int GetPrefLayoutFrameRate();
|
||||
|
||||
/**
|
||||
* Is it possible to use buffer rotation
|
||||
*/
|
||||
static bool BufferRotationEnabled();
|
||||
static void DisableBufferRotation();
|
||||
/**
|
||||
* Are we going to try color management?
|
||||
*/
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "gfxGDIFontList.h"
|
||||
#include "gfxGDIFont.h"
|
||||
|
||||
#include "DeviceManagerD3D9.h"
|
||||
|
||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
#include "gfxDWriteFontList.h"
|
||||
#include "gfxDWriteFonts.h"
|
||||
@ -42,6 +44,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
#include "gfxD2DSurface.h"
|
||||
@ -350,7 +353,8 @@ BuildKeyNameFromFontName(nsAString &aName)
|
||||
}
|
||||
|
||||
gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
: mD3D11DeviceInitialized(false)
|
||||
: mD3D9DeviceInitialized(false)
|
||||
, mD3D11DeviceInitialized(false)
|
||||
{
|
||||
mPrefFonts.Init(50);
|
||||
|
||||
@ -384,6 +388,8 @@ gfxWindowsPlatform::~gfxWindowsPlatform()
|
||||
{
|
||||
NS_UnregisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
||||
|
||||
mDeviceManager = nullptr;
|
||||
|
||||
::ReleaseDC(nullptr, mScreenDC);
|
||||
// not calling FT_Done_FreeType because cairo may still hold references to
|
||||
// these FT_Faces. See bug 458169.
|
||||
@ -1447,6 +1453,29 @@ gfxWindowsPlatform::SetupClearTypeParams()
|
||||
#endif
|
||||
}
|
||||
|
||||
IDirect3DDevice9*
|
||||
gfxWindowsPlatform::GetD3D9Device()
|
||||
{
|
||||
DeviceManagerD3D9* manager = GetD3D9DeviceManager();
|
||||
return manager ? manager->device() : nullptr;
|
||||
}
|
||||
|
||||
DeviceManagerD3D9*
|
||||
gfxWindowsPlatform::GetD3D9DeviceManager()
|
||||
{
|
||||
if (!mD3D9DeviceInitialized) {
|
||||
mD3D9DeviceInitialized = true;
|
||||
|
||||
mDeviceManager = new DeviceManagerD3D9();
|
||||
if (!mDeviceManager->Init()) {
|
||||
NS_WARNING("Could not initialise devive manager");
|
||||
mDeviceManager = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return mDeviceManager;
|
||||
}
|
||||
|
||||
ID3D11Device*
|
||||
gfxWindowsPlatform::GetD3D11Device()
|
||||
{
|
||||
|
@ -43,6 +43,12 @@
|
||||
#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class DeviceManagerD3D9;
|
||||
}
|
||||
}
|
||||
class IDirect3DDevice9;
|
||||
class ID3D11Device;
|
||||
class IDXGIAdapter1;
|
||||
|
||||
@ -265,6 +271,8 @@ public:
|
||||
#else
|
||||
inline bool DWriteEnabled() { return false; }
|
||||
#endif
|
||||
mozilla::layers::DeviceManagerD3D9* GetD3D9DeviceManager();
|
||||
IDirect3DDevice9* GetD3D9Device();
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
cairo_device_t *GetD2DDevice() { return mD2DDevice; }
|
||||
ID3D10Device1 *GetD3D10Device() { return mD2DDevice ? cairo_d2d_device_get_device(mD2DDevice) : nullptr; }
|
||||
@ -297,7 +305,9 @@ private:
|
||||
cairo_device_t *mD2DDevice;
|
||||
#endif
|
||||
mozilla::RefPtr<IDXGIAdapter1> mAdapter;
|
||||
nsRefPtr<mozilla::layers::DeviceManagerD3D9> mDeviceManager;
|
||||
mozilla::RefPtr<ID3D11Device> mD3D11Device;
|
||||
bool mD3D9DeviceInitialized;
|
||||
bool mD3D11DeviceInitialized;
|
||||
|
||||
virtual qcms_profile* GetPlatformCMSOutputProfile();
|
||||
|
@ -1641,14 +1641,14 @@ fuzzy-if(Android&&AndroidVersion>=15,8,100) == 625409-1.html 625409-1-ref.html
|
||||
== 630835-1.html about:blank
|
||||
== 631352-1.html 631352-1-ref.html
|
||||
skip-if(B2G) fails-if(Android) == 632423-1.html 632423-1-ref.html
|
||||
skip-if(Android||B2G) random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == 632781-verybig.html 632781-ref.html
|
||||
skip-if(Android||B2G) random-if(winWidget&&!d2d) == 632781-verybig.html 632781-ref.html
|
||||
== 632781-normalsize.html 632781-ref.html
|
||||
fails-if(Android) == 633344-1.html 633344-1-ref.html
|
||||
== 634232-1.html 634232-1-ref.html
|
||||
fails-if(Android) == 635302-1.html 635302-1-ref.html
|
||||
skip-if(B2G) random-if(d2d) fails-if(Android) == 635373-1.html 635373-1-ref.html
|
||||
skip-if(B2G) random-if(d2d) fails-if(Android) == 635373-2.html 635373-2-ref.html
|
||||
skip-if(B2G) random-if(d2d) fails-if(Android) == 635373-3.html 635373-3-ref.html
|
||||
skip-if(B2G) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,11) == 635373-1.html 635373-1-ref.html
|
||||
skip-if(B2G) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,15) == 635373-2.html 635373-2-ref.html
|
||||
skip-if(B2G) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,15) == 635373-3.html 635373-3-ref.html
|
||||
HTTP(..) == 635639-1.html 635639-1-ref.html
|
||||
HTTP(..) == 635639-2.html 635639-2-ref.html
|
||||
random == 637597-1.html 637597-1-ref.html # bug 637597 was never really fixed!
|
||||
|
@ -17,7 +17,7 @@ random skip-if(Android||B2G) HTTP(..) == object-aspect-ratio-1b.xhtml aspect-rat
|
||||
skip-if(Android||B2G) HTTP(..) == offset-1.xhtml offset-1-ref.html
|
||||
random skip-if(Android||B2G) HTTP(..) == object-aspect-ratio-2a.xhtml aspect-ratio-2-ref.html
|
||||
random skip-if(Android||B2G) HTTP(..) == object-aspect-ratio-2b.xhtml aspect-ratio-2-ref.html
|
||||
skip-if(Android||B2G) skip-if(gtk2Widget) fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),1,56000) fuzzy-if(cocoaWidget,1,56000) fuzzy-if(d2d&&layersGPUAccelerated,1,56000) HTTP(..) == zoomed-1.xhtml zoomed-1-ref.html # bug 778995 for fuzzy
|
||||
skip-if(Android||B2G) skip-if(gtk2Widget) fuzzy-if(winWidget,1,56000) fuzzy-if(cocoaWidget,1,56000) HTTP(..) == zoomed-1.xhtml zoomed-1-ref.html # bug 778995 for fuzzy
|
||||
skip-if(Android||B2G) == poster-1.html poster-ref-blue250x200.html
|
||||
skip-if(Android||B2G) == poster-2.html poster-ref-black140x100.html
|
||||
skip-if(Android||B2G) == poster-3.html poster-ref-black140x100.html
|
||||
|
@ -22,8 +22,8 @@ fails-if(Android) == rotatex-perspective-3a.html rotatex-perspective-3-ref.html
|
||||
skip-if(B2G) == preserve3d-4a.html green-rect.html
|
||||
fuzzy-if(Android&&AndroidVersion>=15,4,300) == preserve3d-5a.html preserve3d-5-ref.html
|
||||
== scale3d-z.html scalez-1-ref.html
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,102,580) fuzzy-if(d2d,143,681) fails-if(Android) fuzzy-if(OSX==10.8,145,752) == scale3d-all.html scale3d-1-ref.html # subpixel AA
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,102,580) fuzzy-if(d2d,143,681) fails-if(Android) fuzzy-if(OSX==10.8,145,752) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
|
||||
fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fails-if(Android) fuzzy-if(OSX==10.8,145,752) == scale3d-all.html scale3d-1-ref.html # subpixel AA
|
||||
fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fails-if(Android) fuzzy-if(OSX==10.8,145,752) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
|
||||
== scale3d-xz.html scale3d-1-ref.html
|
||||
== translatez-1a.html translatez-1-ref.html
|
||||
!= translatez-1b.html translatez-1-ref.html
|
||||
|
@ -17,7 +17,7 @@ random skip-if(Android||B2G) HTTP(..) == object-aspect-ratio-1b.xhtml aspect-rat
|
||||
skip-if(Android||B2G) HTTP(..) == offset-1.xhtml offset-1-ref.html
|
||||
random skip-if(Android||B2G) HTTP(..) == object-aspect-ratio-2a.xhtml aspect-ratio-2-ref.html
|
||||
random skip-if(Android||B2G) HTTP(..) == object-aspect-ratio-2b.xhtml aspect-ratio-2-ref.html
|
||||
skip-if(Android||B2G) skip-if(gtk2Widget) fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),1,56000) fuzzy-if(cocoaWidget,1,56000) fuzzy-if(d2d&&layersGPUAccelerated,1,56000) HTTP(..) == zoomed-1.xhtml zoomed-1-ref.html # bug 778995 for fuzzy
|
||||
skip-if(Android||B2G) skip-if(gtk2Widget) fuzzy-if(winWidget,1,56000) fuzzy-if(cocoaWidget,1,56000) HTTP(..) == zoomed-1.xhtml zoomed-1-ref.html # bug 778995 for fuzzy
|
||||
skip-if(Android||B2G) == poster-1.html poster-ref-blue250x200.html
|
||||
skip-if(Android||B2G) == poster-2.html poster-ref-black140x100.html
|
||||
skip-if(Android||B2G) == poster-3.html poster-ref-black140x100.html
|
||||
|
@ -4088,6 +4088,8 @@ pref("layers.offmainthreadcomposition.async-animations", false);
|
||||
// Whether to prefer normal memory over shared memory. Ignored with cross-process compositing
|
||||
pref("layers.prefer-memory-over-shmem", true);
|
||||
|
||||
pref("layers.bufferrotation.enabled", true);
|
||||
|
||||
#ifdef MOZ_X11
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
pref("gfx.xrender.enabled",true);
|
||||
|
@ -6551,6 +6551,20 @@ nsWindow::StartAllowingD3D9(bool aReinitialize)
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::layers::LayersBackend
|
||||
nsWindow::GetPreferredCompositorBackend()
|
||||
{
|
||||
LayerManagerPrefs prefs;
|
||||
GetLayerManagerPrefs(&prefs);
|
||||
if (prefs.mDisableAcceleration) {
|
||||
return mozilla::layers::LAYERS_BASIC;
|
||||
}
|
||||
if (prefs.mPreferD3D9) {
|
||||
return mozilla::layers::LAYERS_D3D9;
|
||||
}
|
||||
return mozilla::layers::LAYERS_D3D11;
|
||||
}
|
||||
|
||||
bool
|
||||
nsWindow::HasBogusPopupsDropShadowOnMultiMonitor() {
|
||||
if (sHasBogusPopupsDropShadowOnMultiMonitor == TRI_UNKNOWN) {
|
||||
|
@ -273,7 +273,7 @@ public:
|
||||
|
||||
bool const DestroyCalled() { return mDestroyCalled; }
|
||||
|
||||
virtual mozilla::layers::LayersBackend GetPreferredCompositorBackend() { return mozilla::layers::LAYERS_D3D11; }
|
||||
virtual mozilla::layers::LayersBackend GetPreferredCompositorBackend();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -947,10 +947,11 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
|
||||
PLayerTransactionChild* shadowManager;
|
||||
mozilla::layers::LayersBackend backendHint = GetPreferredCompositorBackend();
|
||||
|
||||
bool success;
|
||||
shadowManager = mCompositorChild->SendPLayerTransactionConstructor(
|
||||
backendHint, 0, &textureFactoryIdentifier);
|
||||
backendHint, 0, &textureFactoryIdentifier, &success);
|
||||
|
||||
if (shadowManager) {
|
||||
if (success) {
|
||||
ShadowLayerForwarder* lf = lm->AsShadowForwarder();
|
||||
if (!lf) {
|
||||
delete lm;
|
||||
@ -965,8 +966,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
|
||||
return;
|
||||
}
|
||||
|
||||
// Failed to create a compositor!
|
||||
NS_WARNING("Failed to create an OMT compositor.");
|
||||
NS_ASSERTION(false, "Failed to create an OMT compositor.");
|
||||
DestroyCompositor();
|
||||
// Compositor child had the only reference to LayerManager and will have
|
||||
// deallocated it when being freed.
|
||||
|
Loading…
Reference in New Issue
Block a user