Bug 717393 - Part 2: Refactor clip management and add ClippedMask texture. r=jrmuizel

This commit is contained in:
Bas Schouten 2012-05-15 16:57:51 +02:00
Родитель acc9273cb0
Коммит 66608f2e60
2 изменённых файлов: 95 добавлений и 59 удалений

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

@ -363,29 +363,9 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
RefPtr<ID3D10Texture2D> maskTexture;
RefPtr<ID3D10ShaderResourceView> maskSRView;
if (mPushedClips.size()) {
// Here we render a mask of the clipped out area for use as an input to the
// shadow drawing.
EnsureClipMaskTexture();
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_A8_UNORM,
mSize.width, mSize.height,
1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
hr = mDevice->CreateTexture2D(&desc, NULL, byRef(maskTexture));
RefPtr<ID2D1RenderTarget> rt = CreateRTForTexture(maskTexture);
RefPtr<ID2D1SolidColorBrush> brush;
rt->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), byRef(brush));
RefPtr<ID2D1Geometry> geometry = GetClippedGeometry();
rt->BeginDraw();
rt->Clear(D2D1::ColorF(0, 0));
rt->FillGeometry(geometry, brush);
rt->EndDraw();
mDevice->CreateShaderResourceView(maskTexture, NULL, byRef(maskSRView));
mDevice->CreateShaderResourceView(mCurrentClipMaskTexture, NULL, byRef(maskSRView));
}
IntSize srcSurfSize;
@ -958,6 +938,8 @@ DrawTargetD2D::PushClip(const Path *aPath)
return;
}
mCurrentClipMaskTexture = NULL;
RefPtr<PathD2D> pathD2D = static_cast<PathD2D*>(const_cast<Path*>(aPath));
PushedClip clip;
@ -994,6 +976,7 @@ DrawTargetD2D::PushClip(const Path *aPath)
void
DrawTargetD2D::PushClipRect(const Rect &aRect)
{
mCurrentClipMaskTexture = NULL;
if (!mTransform.IsRectilinear()) {
// Whoops, this isn't a rectangle in device space, Direct2D will not deal
// with this transform the way we want it to.
@ -1025,6 +1008,7 @@ DrawTargetD2D::PushClipRect(const Rect &aRect)
void
DrawTargetD2D::PopClip()
{
mCurrentClipMaskTexture = NULL;
if (mClipsArePushed) {
if (mPushedClips.back().mLayer) {
mRT->PopLayer();
@ -1299,7 +1283,7 @@ DrawTargetD2D::InitD2DRenderTarget()
return false;
}
mRT = CreateRTForTexture(mTexture);
mRT = CreateRTForTexture(mTexture, mFormat);
if (!mRT) {
return false;
@ -1326,24 +1310,7 @@ DrawTargetD2D::PrepareForDrawing(ID2D1RenderTarget *aRT)
mTransformDirty = true;
mClipsArePushed = true;
}
for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
iter != mPushedClips.end(); iter++) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (iter->mLayer) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (mFormat == FORMAT_B8G8R8X8) {
options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
}
aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
iter->mTransform, 1.0f, NULL,
options), iter->mLayer);
} else {
aRT->PushAxisAlignedClip(iter->mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
}
}
PushClipsToRT(aRT);
}
}
FlushTransformToRT();
@ -1470,7 +1437,7 @@ DrawTargetD2D::GetRTForOperation(CompositionOp aOperator, const Pattern &aPatter
return mRT;
}
mTempRT = CreateRTForTexture(mTempTexture);
mTempRT = CreateRTForTexture(mTempTexture, FORMAT_B8G8R8A8);
if (!mTempRT) {
return mRT;
@ -1501,13 +1468,7 @@ DrawTargetD2D::FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aP
return;
}
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
if (mPushedClips[i].mLayer) {
mTempRT->PopLayer();
} else {
mTempRT->PopAxisAlignedClip();
}
}
PopClipsFromRT(mTempRT);
mRT->Flush();
mTempRT->Flush();
@ -1615,7 +1576,7 @@ DrawTargetD2D::GetClippedGeometry()
}
TemporaryRef<ID2D1RenderTarget>
DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture)
DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
{
HRESULT hr;
@ -1634,7 +1595,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture)
D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
if (mFormat == FORMAT_B8G8R8X8 && aTexture == mTexture) {
if (aFormat == FORMAT_B8G8R8X8 && aTexture == mTexture) {
alphaMode = D2D1_ALPHA_MODE_IGNORE;
}
@ -1691,18 +1652,86 @@ void
DrawTargetD2D::PopAllClips()
{
if (mClipsArePushed) {
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
if (mPushedClips[i].mLayer) {
mRT->PopLayer();
} else {
mRT->PopAxisAlignedClip();
}
}
PopClipsFromRT(mRT);
mClipsArePushed = false;
}
}
void
DrawTargetD2D::PushClipsToRT(ID2D1RenderTarget *aRT)
{
for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
iter != mPushedClips.end(); iter++) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (iter->mLayer) {
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
if (mFormat == FORMAT_B8G8R8X8) {
options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
}
aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
iter->mTransform, 1.0f, NULL,
options), iter->mLayer);
} else {
aRT->PushAxisAlignedClip(iter->mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
}
}
}
void
DrawTargetD2D::PopClipsFromRT(ID2D1RenderTarget *aRT)
{
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
if (mPushedClips[i].mLayer) {
aRT->PopLayer();
} else {
aRT->PopAxisAlignedClip();
}
}
}
void
DrawTargetD2D::EnsureClipMaskTexture()
{
if (mCurrentClipMaskTexture) {
return;
}
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_A8_UNORM,
mSize.width,
mSize.height,
1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
HRESULT hr = mDevice->CreateTexture2D(&desc, NULL, byRef(mCurrentClipMaskTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to create texture for ClipMask!";
return;
}
RefPtr<ID2D1RenderTarget> rt = CreateRTForTexture(mCurrentClipMaskTexture, FORMAT_A8);
if (!rt) {
gfxWarning() << "Failed to create RT for ClipMask!";
return;
}
RefPtr<ID2D1SolidColorBrush> brush;
rt->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), byRef(brush));
RefPtr<ID2D1Geometry> geometry = GetClippedGeometry();
rt->BeginDraw();
rt->Clear(D2D1::ColorF(0, 0));
rt->FillGeometry(geometry, brush);
rt->EndDraw();
}
TemporaryRef<ID2D1Brush>
DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
{

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

@ -187,8 +187,14 @@ private:
ID2D1RenderTarget *GetRTForOperation(CompositionOp aOperator, const Pattern &aPattern);
void FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aPattern, const Rect &aBounds); void EnsureViews();
void PopAllClips();
void PushClipsToRT(ID2D1RenderTarget *aRT);
void PopClipsFromRT(ID2D1RenderTarget *aRT);
TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture);
// This function ensures mCurrentClipMaskTexture contains a texture containing
// a mask corresponding with the current DrawTarget clip.
void EnsureClipMaskTexture();
TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
TemporaryRef<ID2D1Geometry> GetClippedGeometry();
TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
@ -208,6 +214,7 @@ private:
RefPtr<ID3D10Device1> mDevice;
RefPtr<ID3D10Texture2D> mTexture;
RefPtr<ID3D10Texture2D> mCurrentClipMaskTexture;
mutable RefPtr<ID2D1RenderTarget> mRT;
// Temporary texture and render target used for supporting alternative operators.