mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-10 05:47:04 +00:00
Bug 874721. CompositorD3D9, r=Bas
This commit is contained in:
parent
fba07cd7c6
commit
e86327c405
@ -446,7 +446,8 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
PaintState result;
|
||||
// We need to disable rotation if we're going to be resampled when
|
||||
// drawing, because we might sample across the rotation boundary.
|
||||
bool canHaveRotation = !(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
|
||||
bool canHaveRotation = gfxPlatform::BufferRotationEnabled() &&
|
||||
!(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
|
||||
|
||||
nsIntRegion validRegion = aLayer->GetValidRegion();
|
||||
|
||||
|
@ -40,6 +40,7 @@ struct YCbCrBufferInfo
|
||||
uint32_t mYHeight;
|
||||
uint32_t mCbCrWidth;
|
||||
uint32_t mCbCrHeight;
|
||||
StereoMode mStereoMode;
|
||||
};
|
||||
|
||||
static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData)
|
||||
@ -103,6 +104,12 @@ gfxIntSize YCbCrImageDataDeserializerBase::GetCbCrSize()
|
||||
return gfxIntSize(info->mCbCrWidth, info->mCbCrHeight);
|
||||
}
|
||||
|
||||
StereoMode YCbCrImageDataDeserializerBase::GetStereoMode()
|
||||
{
|
||||
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
|
||||
return info->mStereoMode;
|
||||
}
|
||||
|
||||
// Offset in bytes
|
||||
static size_t ComputeOffset(uint32_t aHeight, uint32_t aStride)
|
||||
{
|
||||
@ -144,7 +151,8 @@ YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize)
|
||||
|
||||
void
|
||||
YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
const gfx::IntSize& aCbCrSize)
|
||||
const gfx::IntSize& aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
|
||||
info->mYOffset = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
|
||||
@ -157,14 +165,17 @@ YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
info->mYHeight = aYSize.height;
|
||||
info->mCbCrWidth = aCbCrSize.width;
|
||||
info->mCbCrHeight = aCbCrSize.height;
|
||||
info->mStereoMode = aStereoMode;
|
||||
}
|
||||
|
||||
void
|
||||
YCbCrImageDataSerializer::InitializeBufferInfo(const gfxIntSize& aYSize,
|
||||
const gfxIntSize& aCbCrSize)
|
||||
const gfxIntSize& aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
InitializeBufferInfo(gfx::IntSize(aYSize.width, aYSize.height),
|
||||
gfx::IntSize(aCbCrSize.width, aCbCrSize.height));
|
||||
gfx::IntSize(aCbCrSize.width, aCbCrSize.height),
|
||||
aStereoMode);
|
||||
}
|
||||
|
||||
static void CopyLineWithSkip(const uint8_t* src, uint8_t* dst, uint32_t len, uint32_t skip) {
|
||||
|
@ -66,6 +66,11 @@ public:
|
||||
*/
|
||||
gfxIntSize GetCbCrSize();
|
||||
|
||||
/**
|
||||
* Stereo mode for the image.
|
||||
*/
|
||||
StereoMode GetStereoMode();
|
||||
|
||||
/**
|
||||
* Return a pointer to the begining of the data buffer.
|
||||
*/
|
||||
@ -111,9 +116,11 @@ public:
|
||||
* buffer on which we want to store the image.
|
||||
*/
|
||||
void InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
const gfx::IntSize& aCbCrSize);
|
||||
const gfx::IntSize& aCbCrSize,
|
||||
StereoMode aStereoMode);
|
||||
void InitializeBufferInfo(const gfxIntSize& aYSize,
|
||||
const gfxIntSize& aCbCrSize);
|
||||
const gfxIntSize& aCbCrSize,
|
||||
StereoMode aStereoMode);
|
||||
|
||||
bool CopyData(const uint8_t* aYData,
|
||||
const uint8_t* aCbData, const uint8_t* aCrData,
|
||||
|
@ -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,6 +125,10 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
|
||||
result = new DeprecatedTextureClientD3D11(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
}
|
||||
if (parentBackend == LAYERS_D3D9) {
|
||||
result = new DeprecatedTextureClientD3D9(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// fall through to TEXTURE_SHMEM
|
||||
case TEXTURE_SHMEM:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -210,7 +210,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);
|
||||
@ -219,7 +221,8 @@ BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSiz
|
||||
}
|
||||
YCbCrImageDataSerializer serializer(GetBuffer());
|
||||
serializer.InitializeBufferInfo(aYSize,
|
||||
aCbCrSize);
|
||||
aCbCrSize,
|
||||
aStereoMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -549,7 +552,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);
|
||||
|
||||
|
@ -54,7 +54,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;
|
||||
};
|
||||
|
||||
|
||||
@ -207,7 +209,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; }
|
||||
|
||||
|
@ -27,15 +27,11 @@ TemporaryRef<DeprecatedTextureHost> CreateBasicDeprecatedTextureHost(SurfaceDesc
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags);
|
||||
|
||||
#ifdef XP_WIN
|
||||
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostD3D9(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags)
|
||||
{
|
||||
NS_RUNTIMEABORT("not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t aTextureFlags);
|
||||
|
||||
#ifdef XP_WIN
|
||||
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostD3D11(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags);
|
||||
@ -51,11 +47,11 @@ DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptorType aDescri
|
||||
return CreateDeprecatedTextureHostOGL(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#ifdef XP_WIN
|
||||
case LAYERS_D3D9:
|
||||
return CreateDeprecatedTextureHostD3D9(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#ifdef XP_WIN
|
||||
case LAYERS_D3D11:
|
||||
return CreateDeprecatedTextureHostD3D11(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
|
@ -31,6 +31,7 @@ class Compositor;
|
||||
class SurfaceDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureSourceOGL;
|
||||
class TextureSourceD3D9;
|
||||
class TextureSourceD3D11;
|
||||
class TextureSourceBasic;
|
||||
class TextureParent;
|
||||
@ -87,18 +88,11 @@ public:
|
||||
virtual gfx::SurfaceFormat GetFormat() const { return gfx::FORMAT_UNKNOWN; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the OpenGL backend.
|
||||
* Cast to a TextureSource for for each backend..
|
||||
*/
|
||||
virtual TextureSourceOGL* AsSourceOGL() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the D3D11 backend.
|
||||
*/
|
||||
virtual TextureSourceD3D9* AsSourceD3D9() { return nullptr; }
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the software backend.
|
||||
*/
|
||||
virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
|
||||
|
||||
/**
|
||||
|
@ -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());
|
||||
|
560
gfx/layers/d3d9/CompositorD3D9.cpp
Normal file
560
gfx/layers/d3d9/CompositorD3D9.cpp
Normal file
@ -0,0 +1,560 @@
|
||||
/* -*- 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;
|
||||
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;
|
||||
}
|
||||
|
||||
// TODO this method doesn't actually use aSource - do we need it to? (d3d11 doesn't)
|
||||
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::CreateRenderTarget: Failed to create texture"),
|
||||
hr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
device()->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 0, 0);
|
||||
device()->BeginScene();
|
||||
|
||||
if (aClipRectOut) {
|
||||
*aClipRectOut = Rect(0, 0, rect.width, rect.height);
|
||||
}
|
||||
if (aRenderBoundsOut) {
|
||||
*aRenderBoundsOut = Rect(0, 0, rect.width, rect.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 = rect.width;
|
||||
r.bottom = rect.height;
|
||||
}
|
||||
device()->SetScissorRect(&r);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer = mSwapChain->GetBackBuffer();
|
||||
mDefaultRT = new CompositingRenderTargetD3D9(backBuffer,
|
||||
INIT_MODE_CLEAR,
|
||||
IntSize(rect.width, rect.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");
|
||||
}
|
||||
}
|
||||
|
||||
nsIntSize&
|
||||
CompositorD3D9::GetWidgetSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
mSize = rect.Size();
|
||||
|
||||
return mSize;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface((unsigned char*)rect.pBits,
|
||||
gfxIntSize(desc.Width, desc.Height),
|
||||
rect.Pitch,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mTarget->SetSource(imageSurface);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
133
gfx/layers/d3d9/CompositorD3D9.h
Normal file
133
gfx/layers/d3d9/CompositorD3D9.h
Normal file
@ -0,0 +1,133 @@
|
||||
/* -*- 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 nsIntSize& GetWidgetSize() MOZ_OVERRIDE;
|
||||
|
||||
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:
|
||||
void SetSamplerForFilter(gfx::Filter aFilter);
|
||||
void PaintToTarget();
|
||||
void SetMask(const EffectChain &aEffectChain, uint32_t aMaskTexture);
|
||||
|
||||
void ReportFailure(const nsACString &aMsg, HRESULT aCode);
|
||||
|
||||
/* Device manager instance for this compositor */
|
||||
nsRefPtr<DeviceManagerD3D9> mDeviceManager;
|
||||
|
||||
/* Swap chain associated with this compositor */
|
||||
nsRefPtr<SwapChainD3D9> mSwapChain;
|
||||
|
||||
/* Widget associated with this layer manager */
|
||||
nsIWidget *mWidget;
|
||||
|
||||
/*
|
||||
* Context target, NULL when drawing directly to our swap chain.
|
||||
*/
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
RefPtr<CompositingRenderTargetD3D9> mDefaultRT;
|
||||
RefPtr<CompositingRenderTargetD3D9> mCurrentRT;
|
||||
|
||||
nsIntSize mSize;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -12,6 +12,7 @@
|
||||
#include "Nv3DVUtils.h"
|
||||
#include "plstr.h"
|
||||
#include <algorithm>
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -78,6 +79,16 @@ SwapChainD3D9::Init(HWND hWnd)
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<IDirect3DSurface9>
|
||||
SwapChainD3D9::GetBackBuffer()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
return backBuffer.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
SwapChainD3D9::PrepareForRendering()
|
||||
{
|
||||
@ -95,10 +106,7 @@ SwapChainD3D9::PrepareForRendering()
|
||||
}
|
||||
|
||||
if (mSwapChain) {
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer = GetBackBuffer();
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuffer->GetDesc(&desc);
|
||||
@ -116,10 +124,7 @@ SwapChainD3D9::PrepareForRendering()
|
||||
return false;
|
||||
}
|
||||
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
|
||||
backBuffer = GetBackBuffer();
|
||||
mDeviceManager->device()->SetRenderTarget(0, backBuffer);
|
||||
|
||||
return true;
|
||||
@ -139,6 +144,12 @@ SwapChainD3D9::Present(const nsIntRect &aRect)
|
||||
mSwapChain->Present(&r, &r, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainD3D9::Present()
|
||||
{
|
||||
mSwapChain->Present(NULL, NULL, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainD3D9::Reset()
|
||||
{
|
||||
@ -148,9 +159,12 @@ SwapChainD3D9::Reset()
|
||||
#define HAS_CAP(a, b) (((a) & (b)) == (b))
|
||||
#define LACKS_CAP(a, b) !(((a) & (b)) == (b))
|
||||
|
||||
uint32_t DeviceManagerD3D9::sMaskQuadRegister = 11;
|
||||
|
||||
DeviceManagerD3D9::DeviceManagerD3D9()
|
||||
: mDeviceResetCount(0)
|
||||
, mMaxTextureSize(0)
|
||||
, mTextureAddressingMode(D3DTADDRESS_CLAMP)
|
||||
, mHasDynamicTextures(false)
|
||||
, mDeviceWasRemoved(false)
|
||||
{
|
||||
@ -161,9 +175,6 @@ DeviceManagerD3D9::~DeviceManagerD3D9()
|
||||
LayerManagerD3D9::OnDeviceManagerDestroy(this);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(DeviceManagerD3D9)
|
||||
NS_IMPL_RELEASE(DeviceManagerD3D9)
|
||||
|
||||
bool
|
||||
DeviceManagerD3D9::Init()
|
||||
{
|
||||
@ -496,12 +507,12 @@ DeviceManagerD3D9::SetupRenderState()
|
||||
mDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, mTextureAddressingMode);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, mTextureAddressingMode);
|
||||
}
|
||||
|
||||
already_AddRefed<SwapChainD3D9>
|
||||
@ -533,7 +544,7 @@ DeviceManagerD3D9::CreateSwapChain(HWND hWnd)
|
||||
*/
|
||||
bool
|
||||
LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
|
||||
uint32_t aMaskQuadTexture, uint32_t aMaskTexRegister)
|
||||
uint32_t aMaskTexRegister)
|
||||
{
|
||||
gfxIntSize size;
|
||||
nsRefPtr<IDirect3DTexture9> texture =
|
||||
@ -549,7 +560,7 @@ LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
|
||||
gfxRect bounds = gfxRect(gfxPoint(), size);
|
||||
bounds = maskTransform.TransformBounds(bounds);
|
||||
|
||||
aDevice->SetVertexShaderConstantF(aMaskQuadTexture,
|
||||
aDevice->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
|
||||
ShaderConstantRect((float)bounds.x,
|
||||
(float)bounds.y,
|
||||
(float)bounds.width,
|
||||
@ -560,57 +571,10 @@ LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
|
||||
uint32_t
|
||||
DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, MaskType aMaskType)
|
||||
{
|
||||
if (aMask) {
|
||||
// register allocations are taken from LayerManagerD3D9Shaders.h after
|
||||
// the shaders are compiled (genshaders.sh)
|
||||
const uint32_t maskQuadRegister = 11;
|
||||
uint32_t maskTexRegister;
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBPSMask);
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case RGBALAYER:
|
||||
if (aIs2D) {
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBAPSMask);
|
||||
} else {
|
||||
mDevice->SetVertexShader(mLayerVSMask3D);
|
||||
mDevice->SetPixelShader(mRGBAPSMask3D);
|
||||
}
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case COMPONENTLAYERPASS1:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass1PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case COMPONENTLAYERPASS2:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass2PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mYCbCrPSMask);
|
||||
maskTexRegister = 3;
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mSolidColorPSMask);
|
||||
maskTexRegister = 0;
|
||||
break;
|
||||
}
|
||||
if (!LoadMaskTexture(aMask, mDevice, maskQuadRegister, maskTexRegister)) {
|
||||
// if we can't load the mask, fall back to unmasked rendering
|
||||
NS_WARNING("Could not load texture for mask layer.");
|
||||
SetShaderMode(aMode, nullptr, true);
|
||||
}
|
||||
} else {
|
||||
if (aMaskType == MaskNone) {
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
@ -637,6 +601,66 @@ DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
|
||||
mDevice->SetPixelShader(mSolidColorPS);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t maskTexRegister;
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBPSMask);
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case RGBALAYER:
|
||||
if (aMaskType == Mask2d) {
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mRGBAPSMask);
|
||||
} else {
|
||||
mDevice->SetVertexShader(mLayerVSMask3D);
|
||||
mDevice->SetPixelShader(mRGBAPSMask3D);
|
||||
}
|
||||
maskTexRegister = 1;
|
||||
break;
|
||||
case COMPONENTLAYERPASS1:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass1PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case COMPONENTLAYERPASS2:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mComponentPass2PSMask);
|
||||
maskTexRegister = 2;
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mYCbCrPSMask);
|
||||
maskTexRegister = 3;
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVSMask);
|
||||
mDevice->SetPixelShader(mSolidColorPSMask);
|
||||
maskTexRegister = 0;
|
||||
break;
|
||||
}
|
||||
return maskTexRegister;
|
||||
}
|
||||
|
||||
void
|
||||
DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
|
||||
{
|
||||
MaskType maskType = MaskNone;
|
||||
if (aMask) {
|
||||
maskType = aIs2D ? Mask2d : Mask3d;
|
||||
}
|
||||
uint32_t maskTexRegister = SetShaderMode(aMode, maskType);
|
||||
if (aMask) {
|
||||
// register allocations are taken from LayerManagerD3D9Shaders.h after
|
||||
// the shaders are compiled (genshaders.sh)
|
||||
if (!LoadMaskTexture(aMask, mDevice, maskTexRegister)) {
|
||||
// if we can't load the mask, fall back to unmasked rendering
|
||||
NS_WARNING("Could not load texture for mask layer.");
|
||||
SetShaderMode(aMode, MaskNone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,6 +797,13 @@ DeviceManagerD3D9::VerifyCaps()
|
||||
mHasDynamicTextures = true;
|
||||
}
|
||||
|
||||
if (HAS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP) &&
|
||||
LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL)) {
|
||||
mTextureAddressingMode = D3DTADDRESS_WRAP;
|
||||
} else {
|
||||
gfxPlatform::DisableBufferRotation();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "d3d9.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -26,7 +27,39 @@ const int CBmProjection = 4;
|
||||
const int CBvRenderTargetOffset = 8;
|
||||
const int CBvTextureCoords = 9;
|
||||
const int CBvLayerQuad = 10;
|
||||
// we don't use opacity with solid color shaders
|
||||
const int CBfLayerOpacity = 0;
|
||||
const int CBvColor = 0;
|
||||
|
||||
/**
|
||||
* This structure is used to pass rectangles to our shader constant. We can use
|
||||
* this for passing rectangular areas to SetVertexShaderConstant. In the format
|
||||
* of a 4 component float(x,y,width,height). Our vertex shader can then use
|
||||
* this to construct rectangular positions from the 0,0-1,1 quad that we source
|
||||
* it with.
|
||||
*/
|
||||
struct ShaderConstantRect
|
||||
{
|
||||
float mX, mY, mWidth, mHeight;
|
||||
|
||||
// Provide all the commonly used argument types to prevent all the local
|
||||
// casts in the code.
|
||||
ShaderConstantRect(float aX, float aY, float aWidth, float aHeight)
|
||||
: mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
|
||||
: mX((float)aX), mY((float)aY)
|
||||
, mWidth((float)aWidth), mHeight((float)aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, float aWidth, float aHeight)
|
||||
: mX((float)aX), mY((float)aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
// For easy passing to SetVertexShaderConstantF.
|
||||
operator float* () { return &mX; }
|
||||
};
|
||||
|
||||
/**
|
||||
* SwapChain class, this class manages the swap chain belonging to a
|
||||
@ -50,11 +83,14 @@ public:
|
||||
*/
|
||||
bool PrepareForRendering();
|
||||
|
||||
already_AddRefed<IDirect3DSurface9> GetBackBuffer();
|
||||
|
||||
/**
|
||||
* This function will present the selected rectangle of the swap chain to
|
||||
* its associated window.
|
||||
*/
|
||||
void Present(const nsIntRect &aRect);
|
||||
void Present();
|
||||
|
||||
private:
|
||||
friend class DeviceManagerD3D9;
|
||||
@ -83,13 +119,8 @@ class DeviceManagerD3D9 MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
DeviceManagerD3D9();
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
protected:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
NS_DECL_OWNINGTHREAD
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DeviceManagerD3D9)
|
||||
|
||||
public:
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
@ -118,6 +149,8 @@ public:
|
||||
};
|
||||
|
||||
void SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D);
|
||||
// returns the register to be used for the mask texture, if appropriate
|
||||
uint32_t SetShaderMode(ShaderMode aMode, MaskType aMaskType);
|
||||
|
||||
/**
|
||||
* Return pointer to the Nv3DVUtils instance
|
||||
@ -139,6 +172,8 @@ public:
|
||||
|
||||
int32_t GetMaxTextureSize() { return mMaxTextureSize; }
|
||||
|
||||
static uint32_t sMaskQuadRegister;
|
||||
|
||||
private:
|
||||
friend class SwapChainD3D9;
|
||||
|
||||
@ -222,6 +257,12 @@ private:
|
||||
|
||||
uint32_t mMaxTextureSize;
|
||||
|
||||
/**
|
||||
* Wrap (repeat) or clamp textures. We prefer the former so we can do buffer
|
||||
* rotation, but some older hardware doesn't support it.
|
||||
*/
|
||||
D3DTEXTUREADDRESS mTextureAddressingMode;
|
||||
|
||||
/* If this device supports dynamic textures */
|
||||
bool mHasDynamicTextures;
|
||||
|
||||
|
@ -22,36 +22,6 @@ namespace layers {
|
||||
class LayerD3D9;
|
||||
class ThebesLayerD3D9;
|
||||
|
||||
/**
|
||||
* This structure is used to pass rectangles to our shader constant. We can use
|
||||
* this for passing rectangular areas to SetVertexShaderConstant. In the format
|
||||
* of a 4 component float(x,y,width,height). Our vertex shader can then use
|
||||
* this to construct rectangular positions from the 0,0-1,1 quad that we source
|
||||
* it with.
|
||||
*/
|
||||
struct ShaderConstantRect
|
||||
{
|
||||
float mX, mY, mWidth, mHeight;
|
||||
|
||||
// Provide all the commonly used argument types to prevent all the local
|
||||
// casts in the code.
|
||||
ShaderConstantRect(float aX, float aY, float aWidth, float aHeight)
|
||||
: mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
|
||||
: mX((float)aX), mY((float)aY)
|
||||
, mWidth((float)aWidth), mHeight((float)aHeight)
|
||||
{ }
|
||||
|
||||
ShaderConstantRect(int32_t aX, int32_t aY, float aWidth, float aHeight)
|
||||
: mX((float)aX), mY((float)aY), mWidth(aWidth), mHeight(aHeight)
|
||||
{ }
|
||||
|
||||
// For easy passing to SetVertexShaderConstantF.
|
||||
operator float* () { return &mX; }
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the LayerManager used for Direct3D 9. For now this will render on
|
||||
* the main thread.
|
||||
|
617
gfx/layers/d3d9/TextureD3D9.cpp
Normal file
617
gfx/layers/d3d9/TextureD3D9.cpp
Normal file
@ -0,0 +1,617 @@
|
||||
/* -*- 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;
|
||||
mTextures[0]->GetSurfaceLevel(0, getter_AddRefs(mSurface));
|
||||
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(aSurface);
|
||||
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()));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
256
gfx/layers/d3d9/TextureD3D9.h
Normal file
256
gfx/layers/d3d9/TextureD3D9.h
Normal file
@ -0,0 +1,256 @@
|
||||
/* -*- 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);
|
||||
|
||||
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
|
||||
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 */
|
@ -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"
|
||||
@ -625,6 +626,9 @@ 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");
|
||||
|
@ -133,6 +133,7 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface)
|
||||
case SurfaceDescriptor::TRGBImage:
|
||||
DeallocShmem(aSurface->get_RGBImage().data());
|
||||
break;
|
||||
case SurfaceDescriptor::TSurfaceDescriptorD3D9:
|
||||
case SurfaceDescriptor::TSurfaceDescriptorD3D10:
|
||||
break;
|
||||
case SurfaceDescriptor::TMemoryImage:
|
||||
|
@ -36,6 +36,11 @@ union MaybeMagicGrallocBufferHandle {
|
||||
null_t;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorD3D9 {
|
||||
// IDirect3DTexture9*
|
||||
uintptr_t texture;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorD3D10 {
|
||||
WindowsHandle handle;
|
||||
bool hasAlpha;
|
||||
@ -124,6 +129,7 @@ struct SurfaceDescriptorShmem {
|
||||
union SurfaceDescriptor {
|
||||
SurfaceDescriptorShmem;
|
||||
SurfaceDescriptorMemory;
|
||||
SurfaceDescriptorD3D9;
|
||||
SurfaceDescriptorD3D10;
|
||||
SurfaceDescriptorX11;
|
||||
SharedTextureDescriptor;
|
||||
|
@ -119,7 +119,8 @@ SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
|
||||
mSize = aData.mPicSize;
|
||||
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
@ -153,7 +154,8 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrImage::Data& aData)
|
||||
|
||||
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
MOZ_ASSERT(serializer.IsValid());
|
||||
|
||||
aData.mYChannel = serializer.GetYData();
|
||||
@ -239,7 +241,8 @@ DeprecatedSharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
|
||||
mSize = aData.mPicSize;
|
||||
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
@ -269,7 +272,8 @@ DeprecatedSharedPlanarYCbCrImage::Allocate(PlanarYCbCrImage::Data& aData)
|
||||
|
||||
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize);
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
if (!serializer.IsValid() || mShmem.Size<uint8_t>() < size) {
|
||||
mSurfaceAllocator->DeallocShmem(mShmem);
|
||||
return false;
|
||||
|
@ -52,7 +52,13 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
'd3d9/DeviceManagerD3D9.h',
|
||||
'd3d9/LayerManagerD3D9.h',
|
||||
]
|
||||
EXPORTS.mozilla.layers += [
|
||||
'CompositorD3D9.h',
|
||||
'TextureD3D9.h',
|
||||
]
|
||||
CPP_SOURCES += [
|
||||
'CompositorD3D9.cpp',
|
||||
'TextureD3D9.cpp',
|
||||
'LayerManagerD3D9.cpp',
|
||||
'ThebesLayerD3D9.cpp',
|
||||
'ContainerLayerD3D9.cpp',
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
#include "nsIGfxInfo.h"
|
||||
|
||||
@ -86,6 +87,8 @@ using namespace mozilla::layers;
|
||||
gfxPlatform *gPlatform = nullptr;
|
||||
static bool gEverInitialized = false;
|
||||
|
||||
static Mutex* gGfxPlatformPrefsLock = nullptr;
|
||||
|
||||
// These two may point to the same profile
|
||||
static qcms_profile *gCMSOutputProfile = nullptr;
|
||||
static qcms_profile *gCMSsRGBProfile = nullptr;
|
||||
@ -313,6 +316,8 @@ gfxPlatform::Init()
|
||||
sCmapDataLog = PR_NewLogModule("cmapdata");;
|
||||
#endif
|
||||
|
||||
gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
|
||||
|
||||
/* Initialize the GfxInfo service.
|
||||
* Note: we can't call functions on GfxInfo that depend
|
||||
* on gPlatform until after it has been initialized
|
||||
@ -475,6 +480,8 @@ gfxPlatform::Shutdown()
|
||||
|
||||
CompositorParent::ShutDown();
|
||||
|
||||
delete gGfxPlatformPrefsLock;
|
||||
|
||||
delete gPlatform;
|
||||
gPlatform = nullptr;
|
||||
}
|
||||
@ -1856,11 +1863,15 @@ static bool sPrefLayersAccelerationForceEnabled = false;
|
||||
static bool sPrefLayersAccelerationDisabled = false;
|
||||
static bool sPrefLayersPreferOpenGL = false;
|
||||
static bool sPrefLayersPreferD3D9 = false;
|
||||
static bool sLayersSupportsD3D9 = true;
|
||||
static int sPrefLayoutFrameRate = -1;
|
||||
static bool sBufferRotationEnabled = false;
|
||||
|
||||
void InitLayersAccelerationPrefs()
|
||||
static bool sLayersAccelerationPrefsInitialized = false;
|
||||
|
||||
void
|
||||
InitLayersAccelerationPrefs()
|
||||
{
|
||||
static bool sLayersAccelerationPrefsInitialized = false;
|
||||
if (!sLayersAccelerationPrefsInitialized)
|
||||
{
|
||||
sPrefLayersOffMainThreadCompositionEnabled = Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
|
||||
@ -1871,12 +1882,24 @@ void InitLayersAccelerationPrefs()
|
||||
sPrefLayersPreferOpenGL = Preferences::GetBool("layers.prefer-opengl", false);
|
||||
sPrefLayersPreferD3D9 = Preferences::GetBool("layers.prefer-d3d9", false);
|
||||
sPrefLayoutFrameRate = Preferences::GetInt("layout.frame_rate", -1);
|
||||
sBufferRotationEnabled = Preferences::GetBool("layers.bufferrotation.enabled", true);
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
if (gfxInfo) {
|
||||
int32_t status;
|
||||
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, &status))) {
|
||||
if (status != nsIGfxInfo::FEATURE_NO_INFO && !sPrefLayersAccelerationForceEnabled) {
|
||||
sLayersSupportsD3D9 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sLayersAccelerationPrefsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersOffMainThreadCompositionEnabled()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersOffMainThreadCompositionEnabled()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersOffMainThreadCompositionEnabled ||
|
||||
@ -1884,13 +1907,15 @@ bool gfxPlatform::GetPrefLayersOffMainThreadCompositionEnabled()
|
||||
sPrefLayersOffMainThreadCompositionTestingEnabled;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersOffMainThreadCompositionForceEnabled()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersOffMainThreadCompositionForceEnabled()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersOffMainThreadCompositionForceEnabled;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersAccelerationForceEnabled()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersAccelerationForceEnabled()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersAccelerationForceEnabled;
|
||||
@ -1903,20 +1928,49 @@ gfxPlatform::GetPrefLayersAccelerationDisabled()
|
||||
return sPrefLayersAccelerationDisabled;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersPreferOpenGL()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersPreferOpenGL()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersPreferOpenGL;
|
||||
}
|
||||
|
||||
bool gfxPlatform::GetPrefLayersPreferD3D9()
|
||||
bool
|
||||
gfxPlatform::GetPrefLayersPreferD3D9()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayersPreferD3D9;
|
||||
}
|
||||
|
||||
int gfxPlatform::GetPrefLayoutFrameRate()
|
||||
bool
|
||||
gfxPlatform::CanUseDirect3D9()
|
||||
{
|
||||
// this function is called from the compositor thread, so it is not
|
||||
// safe to init the prefs etc. from here.
|
||||
MOZ_ASSERT(sLayersAccelerationPrefsInitialized);
|
||||
return sLayersSupportsD3D9;
|
||||
}
|
||||
|
||||
int
|
||||
gfxPlatform::GetPrefLayoutFrameRate()
|
||||
{
|
||||
InitLayersAccelerationPrefs();
|
||||
return sPrefLayoutFrameRate;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatform::BufferRotationEnabled()
|
||||
{
|
||||
MutexAutoLock autoLock(*gGfxPlatformPrefsLock);
|
||||
|
||||
InitLayersAccelerationPrefs();
|
||||
return sBufferRotationEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::DisableBufferRotation()
|
||||
{
|
||||
MutexAutoLock autoLock(*gGfxPlatformPrefsLock);
|
||||
|
||||
sBufferRotationEnabled = false;
|
||||
}
|
||||
|
@ -471,8 +471,14 @@ public:
|
||||
static bool GetPrefLayersAccelerationDisabled();
|
||||
static bool GetPrefLayersPreferOpenGL();
|
||||
static bool GetPrefLayersPreferD3D9();
|
||||
static bool CanUseDirect3D9();
|
||||
static int GetPrefLayoutFrameRate();
|
||||
|
||||
/**
|
||||
* Is it possible to use buffer rotation
|
||||
*/
|
||||
static bool BufferRotationEnabled();
|
||||
static void DisableBufferRotation();
|
||||
/**
|
||||
* Are we going to try color management?
|
||||
*/
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "gfxGDIFontList.h"
|
||||
#include "gfxGDIFont.h"
|
||||
|
||||
#include "DeviceManagerD3D9.h"
|
||||
|
||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
#include "gfxDWriteFontList.h"
|
||||
#include "gfxDWriteFonts.h"
|
||||
@ -42,6 +44,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
#include "gfxD2DSurface.h"
|
||||
@ -350,7 +353,8 @@ BuildKeyNameFromFontName(nsAString &aName)
|
||||
}
|
||||
|
||||
gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
: mD3D11DeviceInitialized(false)
|
||||
: mD3D9DeviceInitialized(false)
|
||||
, mD3D11DeviceInitialized(false)
|
||||
{
|
||||
mPrefFonts.Init(50);
|
||||
|
||||
@ -384,6 +388,8 @@ gfxWindowsPlatform::~gfxWindowsPlatform()
|
||||
{
|
||||
NS_UnregisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
||||
|
||||
mDeviceManager = nullptr;
|
||||
|
||||
::ReleaseDC(nullptr, mScreenDC);
|
||||
// not calling FT_Done_FreeType because cairo may still hold references to
|
||||
// these FT_Faces. See bug 458169.
|
||||
@ -1447,6 +1453,29 @@ gfxWindowsPlatform::SetupClearTypeParams()
|
||||
#endif
|
||||
}
|
||||
|
||||
IDirect3DDevice9*
|
||||
gfxWindowsPlatform::GetD3D9Device()
|
||||
{
|
||||
DeviceManagerD3D9* manager = GetD3D9DeviceManager();
|
||||
return manager ? manager->device() : nullptr;
|
||||
}
|
||||
|
||||
DeviceManagerD3D9*
|
||||
gfxWindowsPlatform::GetD3D9DeviceManager()
|
||||
{
|
||||
if (!mD3D9DeviceInitialized) {
|
||||
mD3D9DeviceInitialized = true;
|
||||
|
||||
mDeviceManager = new DeviceManagerD3D9();
|
||||
if (!mDeviceManager->Init()) {
|
||||
NS_WARNING("Could not initialise devive manager");
|
||||
mDeviceManager = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return mDeviceManager;
|
||||
}
|
||||
|
||||
ID3D11Device*
|
||||
gfxWindowsPlatform::GetD3D11Device()
|
||||
{
|
||||
|
@ -43,6 +43,12 @@
|
||||
#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class DeviceManagerD3D9;
|
||||
}
|
||||
}
|
||||
class IDirect3DDevice9;
|
||||
class ID3D11Device;
|
||||
class IDXGIAdapter1;
|
||||
|
||||
@ -265,6 +271,8 @@ public:
|
||||
#else
|
||||
inline bool DWriteEnabled() { return false; }
|
||||
#endif
|
||||
mozilla::layers::DeviceManagerD3D9* GetD3D9DeviceManager();
|
||||
IDirect3DDevice9* GetD3D9Device();
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
cairo_device_t *GetD2DDevice() { return mD2DDevice; }
|
||||
ID3D10Device1 *GetD3D10Device() { return mD2DDevice ? cairo_d2d_device_get_device(mD2DDevice) : nullptr; }
|
||||
@ -297,7 +305,9 @@ private:
|
||||
cairo_device_t *mD2DDevice;
|
||||
#endif
|
||||
mozilla::RefPtr<IDXGIAdapter1> mAdapter;
|
||||
nsRefPtr<mozilla::layers::DeviceManagerD3D9> mDeviceManager;
|
||||
mozilla::RefPtr<ID3D11Device> mD3D11Device;
|
||||
bool mD3D9DeviceInitialized;
|
||||
bool mD3D11DeviceInitialized;
|
||||
|
||||
virtual qcms_profile* GetPlatformCMSOutputProfile();
|
||||
|
@ -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);
|
||||
|
@ -6554,6 +6554,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) {
|
||||
|
@ -274,7 +274,7 @@ public:
|
||||
|
||||
bool const DestroyCalled() { return mDestroyCalled; }
|
||||
|
||||
virtual mozilla::layers::LayersBackend GetPreferredCompositorBackend() { return mozilla::layers::LAYERS_D3D11; }
|
||||
virtual mozilla::layers::LayersBackend GetPreferredCompositorBackend();
|
||||
|
||||
protected:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user