This commit is contained in:
Doug Turner 2011-01-19 20:45:20 -08:00
Родитель 2ecfdb6185
Коммит 6ae0d1cace
4 изменённых файлов: 41 добавлений и 147 удалений

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

@ -43,9 +43,6 @@
#include "gfxD2DSurface.h"
#endif
#include "gfxTeeSurface.h"
#include "gfxUtils.h"
namespace mozilla {
namespace layers {
@ -120,9 +117,7 @@ ThebesLayerD3D10::RenderLayer()
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;
if (mTextureOnWhite) {
technique = effect()->GetTechniqueByName("RenderComponentAlphaLayer");
} else if (CanUseOpaqueSurface()) {
if (CanUseOpaqueSurface()) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
@ -135,9 +130,6 @@ ThebesLayerD3D10::RenderLayer()
if (mSRView) {
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);
}
if (mSRViewOnWhite) {
effect()->GetVariableByName("tRGBWhite")->AsShaderResource()->SetResource(mSRViewOnWhite);
}
while ((iterRect = iter.Next())) {
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
@ -172,28 +164,19 @@ ThebesLayerD3D10::Validate()
return;
}
SurfaceMode mode = GetSurfaceMode();
if (mode == SURFACE_COMPONENT_ALPHA &&
(!mParent || !mParent->SupportsComponentAlphaChildren())) {
mode = SURFACE_SINGLE_CHANNEL_ALPHA;
}
VerifyContentType(mode);
VerifyContentType();
nsIntRect visibleRect = mVisibleRegion.GetBounds();
if (mTexture) {
if (!mTextureRegion.IsEqual(mVisibleRegion)) {
nsRefPtr<ID3D10Texture2D> oldTexture = mTexture;
mTexture = nsnull;
nsRefPtr<ID3D10Texture2D> oldTextureOnWhite = mTextureOnWhite;
mTextureOnWhite = nsnull;
nsIntRegion retainRegion = mTextureRegion;
nsIntRect oldBounds = mTextureRegion.GetBounds();
nsIntRect newBounds = mVisibleRegion.GetBounds();
CreateNewTextures(gfxIntSize(newBounds.width, newBounds.height), mode);
CreateNewTexture(gfxIntSize(newBounds.width, newBounds.height));
// Old visible region will become the region that is covered by both the
// old and the new visible region.
@ -216,18 +199,13 @@ ThebesLayerD3D10::Validate()
CopyRegion(oldTexture, oldBounds.TopLeft(),
mTexture, newBounds.TopLeft(),
retainRegion, &mValidRegion);
if (oldTextureOnWhite) {
CopyRegion(oldTextureOnWhite, oldBounds.TopLeft(),
mTextureOnWhite, newBounds.TopLeft(),
retainRegion, &mValidRegion);
}
}
mTextureRegion = mVisibleRegion;
}
}
if (!mTexture || (mode == SURFACE_COMPONENT_ALPHA && !mTextureOnWhite)) {
CreateNewTextures(gfxIntSize(visibleRect.width, visibleRect.height), mode);
if (!mTexture) {
CreateNewTexture(gfxIntSize(visibleRect.width, visibleRect.height));
mValidRegion.SetEmpty();
}
@ -247,7 +225,7 @@ ThebesLayerD3D10::Validate()
nsIntRegion region;
region.Sub(mVisibleRegion, mValidRegion);
DrawRegion(region, mode);
DrawRegion(region);
mValidRegion = mVisibleRegion;
}
@ -266,47 +244,27 @@ ThebesLayerD3D10::GetLayer()
}
void
ThebesLayerD3D10::VerifyContentType(SurfaceMode aMode)
ThebesLayerD3D10::VerifyContentType()
{
if (mD2DSurface) {
gfxASurface::gfxContentType type = aMode != SURFACE_SINGLE_CHANNEL_ALPHA ?
gfxASurface::gfxContentType type = CanUseOpaqueSurface() ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA;
if (type != mD2DSurface->GetContentType()) {
mD2DSurface = new gfxD2DSurface(mTexture, type);
if (!mD2DSurface || mD2DSurface->CairoStatus()) {
NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
mD2DSurface = nsnull;
return;
}
if (type != mD2DSurface->GetContentType()) {
mD2DSurface = new gfxD2DSurface(mTexture, type);
mValidRegion.SetEmpty();
}
if (aMode != SURFACE_COMPONENT_ALPHA && mTextureOnWhite) {
// If we've transitioned away from component alpha, we can delete those resources.
mD2DSurfaceOnWhite = nsnull;
mSRViewOnWhite = nsnull;
mTextureOnWhite = nsnull;
if (!mD2DSurface || mD2DSurface->CairoStatus()) {
NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
mD2DSurface = nsnull;
return;
}
mValidRegion.SetEmpty();
}
}
}
static void
FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
const nsIntPoint& aOffset, const gfxRGBA& aColor)
{
nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
gfxUtils::PathForRegion(ctx, aRegion);
ctx->SetColor(aColor);
ctx->Fill();
}
void
ThebesLayerD3D10::DrawRegion(const nsIntRegion &aRegion, SurfaceMode aMode)
ThebesLayerD3D10::DrawRegion(const nsIntRegion &aRegion)
{
nsIntRect visibleRect = mVisibleRegion.GetBounds();
@ -314,22 +272,7 @@ ThebesLayerD3D10::DrawRegion(const nsIntRegion &aRegion, SurfaceMode aMode)
return;
}
nsRefPtr<gfxASurface> destinationSurface;
if (aMode == SURFACE_COMPONENT_ALPHA) {
FillSurface(mD2DSurface, aRegion, visibleRect.TopLeft(), gfxRGBA(0.0, 0.0, 0.0, 1.0));
FillSurface(mD2DSurfaceOnWhite, aRegion, visibleRect.TopLeft(), gfxRGBA(1.0, 1.0, 1.0, 1.0));
gfxASurface* surfaces[2] = { mD2DSurface.get(), mD2DSurfaceOnWhite.get() };
destinationSurface = new gfxTeeSurface(surfaces, NS_ARRAY_LENGTH(surfaces));
// Using this surface as a source will likely go horribly wrong, since
// only the onBlack surface will really be used, so alpha information will
// be incorrect.
destinationSurface->SetAllowUseAsSource(PR_FALSE);
} else {
destinationSurface = mD2DSurface;
}
nsRefPtr<gfxContext> context = new gfxContext(destinationSurface);
nsRefPtr<gfxContext> context = new gfxContext(mD2DSurface);
nsIntRegionRectIterator iter(aRegion);
context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
@ -340,7 +283,7 @@ ThebesLayerD3D10::DrawRegion(const nsIntRegion &aRegion, SurfaceMode aMode)
}
context->Clip();
if (aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
if (mD2DSurface->GetContentType() != gfxASurface::CONTENT_COLOR) {
context->SetOperator(gfxContext::OPERATOR_CLEAR);
context->Paint();
context->SetOperator(gfxContext::OPERATOR_OVER);
@ -353,7 +296,7 @@ ThebesLayerD3D10::DrawRegion(const nsIntRegion &aRegion, SurfaceMode aMode)
}
void
ThebesLayerD3D10::CreateNewTextures(const gfxIntSize &aSize, SurfaceMode aMode)
ThebesLayerD3D10::CreateNewTexture(const gfxIntSize &aSize)
{
if (aSize.width == 0 || aSize.height == 0) {
// Nothing to do.
@ -363,54 +306,27 @@ ThebesLayerD3D10::CreateNewTextures(const gfxIntSize &aSize, SurfaceMode aMode)
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
HRESULT hr;
if (!mTexture) {
hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture));
if (FAILED(hr)) {
NS_WARNING("Failed to create new texture for ThebesLayerD3D10!");
return;
}
hr = device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
if (FAILED(hr)) {
NS_WARNING("Failed to create shader resource view for ThebesLayerD3D10.");
}
mD2DSurface = new gfxD2DSurface(mTexture, aMode != SURFACE_SINGLE_CHANNEL_ALPHA ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA);
if (!mD2DSurface || mD2DSurface->CairoStatus()) {
NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
mD2DSurface = nsnull;
return;
}
HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture));
if (FAILED(hr)) {
NS_WARNING("Failed to create new texture for ThebesLayerD3D10!");
return;
}
if (aMode == SURFACE_COMPONENT_ALPHA && !mTextureOnWhite) {
hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTextureOnWhite));
hr = device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
if (FAILED(hr)) {
NS_WARNING("Failed to create new texture for ThebesLayerD3D10!");
return;
}
if (FAILED(hr)) {
NS_WARNING("Failed to create shader resource view for ThebesLayerD3D10.");
}
hr = device()->CreateShaderResourceView(mTextureOnWhite, NULL, getter_AddRefs(mSRViewOnWhite));
mD2DSurface = new gfxD2DSurface(mTexture, CanUseOpaqueSurface() ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA);
if (FAILED(hr)) {
NS_WARNING("Failed to create shader resource view for ThebesLayerD3D10.");
}
mD2DSurfaceOnWhite = new gfxD2DSurface(mTextureOnWhite, gfxASurface::CONTENT_COLOR);
if (!mD2DSurfaceOnWhite || mD2DSurfaceOnWhite->CairoStatus()) {
NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
mD2DSurfaceOnWhite = nsnull;
return;
}
if (!mD2DSurface || mD2DSurface->CairoStatus()) {
NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
mD2DSurface = nsnull;
return;
}
}

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

@ -67,29 +67,20 @@ private:
/* Shader resource view for our texture */
nsRefPtr<ID3D10ShaderResourceView> mSRView;
/* Texture for render-on-whitew when doing component alpha */
nsRefPtr<ID3D10Texture2D> mTextureOnWhite;
/* Shader resource view for our render-on-white texture */
nsRefPtr<ID3D10ShaderResourceView> mSRViewOnWhite;
/* Visible region used when we drew the contents of the textures */
nsIntRegion mTextureRegion;
/* Checks if our D2D surface has the right content type */
void VerifyContentType(SurfaceMode aMode);
void VerifyContentType();
/* This contains the thebes surface */
nsRefPtr<gfxASurface> mD2DSurface;
/* This contains the thebes surface for our render-on-white texture */
nsRefPtr<gfxASurface> mD2DSurfaceOnWhite;
/* Have a region of our layer drawn */
void DrawRegion(const nsIntRegion &aRegion, SurfaceMode aMode);
void DrawRegion(const nsIntRegion &aRegion);
/* Create a new texture */
void CreateNewTextures(const gfxIntSize &aSize, SurfaceMode aMode);
void CreateNewTexture(const gfxIntSize &aSize);
/* Copy a texture region */
void CopyRegion(ID3D10Texture2D* aSrc, const nsIntPoint &aSrcOffset,

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

@ -434,10 +434,9 @@ gfxUtils::ImageFormatToDepth(gfxASurface::gfxImageFormat aFormat)
}
return 0;
}
static void
PathForRegionInternal(gfxContext* aContext, const nsIntRegion& aRegion,
PRBool aSnap)
ClipToRegionInternal(gfxContext* aContext, const nsIntRegion& aRegion,
PRBool aSnap)
{
aContext->NewPath();
nsIntRegionRectIterator iter(aRegion);
@ -445,26 +444,19 @@ PathForRegionInternal(gfxContext* aContext, const nsIntRegion& aRegion,
while ((r = iter.Next()) != nsnull) {
aContext->Rectangle(gfxRect(r->x, r->y, r->width, r->height), aSnap);
}
aContext->Clip();
}
/*static*/ void
gfxUtils::ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion)
{
PathForRegionInternal(aContext, aRegion, PR_FALSE);
aContext->Clip();
ClipToRegionInternal(aContext, aRegion, PR_FALSE);
}
/*static*/ void
gfxUtils::ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion)
{
PathForRegionInternal(aContext, aRegion, PR_TRUE);
aContext->Clip();
}
/*static*/ void
gfxUtils::PathForRegion(gfxContext* aContext, const nsIntRegion& aRegion)
{
PathForRegionInternal(aContext, aRegion, PR_FALSE);
ClipToRegionInternal(aContext, aRegion, PR_TRUE);
}
PRBool

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

@ -96,11 +96,6 @@ public:
*/
static void ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);
/**
* Draw a path around aRegion.
*/
static void PathForRegion(gfxContext* aContext, const nsIntRegion& aRegion);
/*
* Convert image format to depth value
*/