Bug 874721, bug 899435. D3D9 compositor and windows OMTC window resizing. r=Bas, mattwoodrow

This commit is contained in:
Nicholas Cameron 2013-08-04 19:46:17 +12:00
parent 102bdb9382
commit dd58f82344
60 changed files with 2213 additions and 286 deletions

View File

@ -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();

View File

@ -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)

View File

@ -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();

View File

@ -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) {

View File

@ -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,

View File

@ -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>

View File

@ -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");
}

View File

@ -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(),

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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());

View File

@ -18,6 +18,7 @@ CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
: mTextureInfo(aTextureInfo)
, mCompositor(nullptr)
, mLayer(nullptr)
, mAttached(false)
{
MOZ_COUNT_CTOR(CompositableHost);
}

View File

@ -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;

View File

@ -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());

View File

@ -86,6 +86,7 @@ LayerManagerComposite::ClearCachedResources(Layer* aSubtree)
LayerManagerComposite::LayerManagerComposite(Compositor* aCompositor)
: mCompositor(aCompositor)
{
MOZ_ASSERT(aCompositor);
}
LayerManagerComposite::~LayerManagerComposite()

View File

@ -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,

View File

@ -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; }
/**

View File

@ -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());

View File

@ -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);

View File

@ -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;

View File

@ -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*

View File

@ -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;

View File

@ -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());

View 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);
}
}
}

View 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

View File

@ -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;
}

View File

@ -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;

View File

@ -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.

View 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;
}
}
}
}

View 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 */

View File

@ -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

View File

@ -73,7 +73,8 @@ CompositorChild::Get()
PLayerTransactionChild*
CompositorChild::AllocPLayerTransactionChild(const LayersBackend& aBackendHint,
const uint64_t& aId,
TextureFactoryIdentifier*)
TextureFactoryIdentifier*,
bool*)
{
return new LayerTransactionChild();
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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();

View File

@ -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:

View File

@ -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;

View File

@ -60,7 +60,7 @@ parent:
sync FlushRendering();
sync PLayerTransaction(LayersBackend layersBackendHint, uint64_t id)
returns (TextureFactoryIdentifier textureFactoryIdentifier);
returns (TextureFactoryIdentifier textureFactoryIdentifier, bool success);
};
} // layers

View File

@ -161,6 +161,7 @@ void
CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
{
mTextureFactoryIdentifier = aIdentifier;
mMultiProcess = aIdentifier.mParentProcessId != XRE_GetProcessType();
}
ShadowLayerForwarder::ShadowLayerForwarder()

View File

@ -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;

View File

@ -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',

View File

@ -44,6 +44,7 @@ public:
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
{
return TextureFactoryIdentifier(LAYERS_OPENGL,
XRE_GetProcessType(),
GetMaxTextureSize(),
mFBOTextureTarget == LOCAL_GL_TEXTURE_2D,
SupportsPartialTextureUpdate());

View File

@ -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;
}

View File

@ -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; }
};

View File

@ -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());

View File

@ -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 */

View File

@ -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;
}

View File

@ -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?
*/

View File

@ -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()
{

View File

@ -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();

View File

@ -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!

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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:

View File

@ -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.