author | Bas Schouten <bschouten@mozilla.com> |
Thu, 21 Oct 2010 22:41:04 +0200 | |
changeset 56334 | 73f8c0079bc185475435f2d27d2650f461f1ffec |
parent 56333 | 39c2e0d65ad14bf10276596497d55b56f58ecca7 |
child 56335 | f4a06cca9fb95118a0565c5b58d2ee1f24f6b0f5 |
push id | 16487 |
push user | bschouten@mozilla.com |
push date | Thu, 21 Oct 2010 20:42:12 +0000 |
treeherder | mozilla-central@f4a06cca9fb9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc, blocking-betaN |
bugs | 584494 |
milestone | 2.0b8pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/d3d9/CanvasLayerD3D9.cpp +++ b/gfx/layers/d3d9/CanvasLayerD3D9.cpp @@ -222,17 +222,17 @@ CanvasLayerD3D9::Updated(const nsIntRect Layer* CanvasLayerD3D9::GetLayer() { return this; } void -CanvasLayerD3D9::RenderLayer() +CanvasLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) { if (!mTexture) { Updated(mBounds); } /* * We flip the Y axis here, note we can only do this because we are in * CULL_NONE mode! @@ -241,17 +241,18 @@ CanvasLayerD3D9::RenderLayer() ShaderConstantRect quad(0, 0, mBounds.width, mBounds.height); if (mNeedsYFlip) { quad.mHeight = (float)-mBounds.height; quad.mY = (float)mBounds.height; } device()->SetVertexShaderConstantF(CBvLayerQuad, quad, 1); - device()->SetVertexShaderConstantF(CBmLayerTransform, &mTransform._11, 4); + gfx3DMatrix transform = mTransform * aTransform; + device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); 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] = GetOpacity(); device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1);
--- a/gfx/layers/d3d9/CanvasLayerD3D9.h +++ b/gfx/layers/d3d9/CanvasLayerD3D9.h @@ -65,17 +65,17 @@ public: ~CanvasLayerD3D9(); // CanvasLayer implementation virtual void Initialize(const Data& aData); virtual void Updated(const nsIntRect& aRect); // LayerD3D9 implementation virtual Layer* GetLayer(); - virtual void RenderLayer(); + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); virtual void CleanResources(); virtual void LayerManagerDestroyed(); void CreateTexture(); protected: typedef mozilla::gl::GLContext GLContext;
--- a/gfx/layers/d3d9/ColorLayerD3D9.cpp +++ b/gfx/layers/d3d9/ColorLayerD3D9.cpp @@ -43,39 +43,40 @@ namespace layers { Layer* ColorLayerD3D9::GetLayer() { return this; } void -ColorLayerD3D9::RenderLayer() +ColorLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) { // XXX we might be able to improve performance by using // IDirect3DDevice9::Clear nsIntRect visibleRect = mVisibleRegion.GetBounds(); device()->SetVertexShaderConstantF( CBvLayerQuad, ShaderConstantRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height), 1); - device()->SetVertexShaderConstantF(CBmLayerTransform, &mTransform._11, 4); + gfx3DMatrix transform = mTransform * aTransform; + device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); float color[4]; // color is premultiplied, so we need to adjust all channels - color[0] = (float)(mColor.r * GetOpacity()); - color[1] = (float)(mColor.g * GetOpacity()); - color[2] = (float)(mColor.b * GetOpacity()); - color[3] = (float)(mColor.a * GetOpacity()); + color[0] = (float)(mColor.r * GetOpacity() * aOpacity); + color[1] = (float)(mColor.g * GetOpacity() * aOpacity); + color[2] = (float)(mColor.b * GetOpacity() * aOpacity); + color[3] = (float)(mColor.a * GetOpacity() * aOpacity); device()->SetPixelShaderConstantF(0, color, 1); mD3DManager->SetShaderMode(DeviceManagerD3D9::SOLIDCOLORLAYER); device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); }
--- a/gfx/layers/d3d9/ColorLayerD3D9.h +++ b/gfx/layers/d3d9/ColorLayerD3D9.h @@ -53,15 +53,15 @@ public: , LayerD3D9(aManager) { mImplData = static_cast<LayerD3D9*>(this); } // LayerD3D9 Implementation virtual Layer* GetLayer(); - virtual void RenderLayer(); + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); }; } /* layers */ } /* mozilla */ #endif /* GFX_COLORLAYERD3D9_H */
--- a/gfx/layers/d3d9/ContainerLayerD3D9.cpp +++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp @@ -130,32 +130,33 @@ ContainerLayerD3D9::GetFirstChildD3D9() { if (!mFirstChild) { return nsnull; } return static_cast<LayerD3D9*>(mFirstChild->ImplData()); } void -ContainerLayerD3D9::RenderLayer() +ContainerLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) { - float opacity = GetOpacity(); + float opacity = GetOpacity() * aOpacity; nsRefPtr<IDirect3DSurface9> previousRenderTarget; nsRefPtr<IDirect3DTexture9> renderTexture; float previousRenderTargetOffset[4]; RECT oldClipRect; float renderTargetOffset[] = { 0, 0, 0, 0 }; float oldViewMatrix[4][4]; + gfx3DMatrix transform = mTransform * aTransform; + nsIntRect visibleRect = mVisibleRegion.GetBounds(); - PRBool useIntermediate = (opacity != 1.0 || !mTransform.IsIdentity()); + PRBool useIntermediate = ShouldUseIntermediate(opacity, transform); if (useIntermediate) { device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget)); - device()->GetScissorRect(&oldClipRect); device()->CreateTexture(visibleRect.width, visibleRect.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, getter_AddRefs(renderTexture), NULL); nsRefPtr<IDirect3DSurface9> renderSurface; renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface)); device()->SetRenderTarget(0, renderSurface); device()->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0); @@ -179,68 +180,83 @@ ContainerLayerD3D9::RenderLayer() } /* * Render this container's contents. */ LayerD3D9 *layerToRender = GetFirstChildD3D9(); while (layerToRender) { const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect(); - RECT r; - if (clipRect) { - r.left = (LONG)(clipRect->x - renderTargetOffset[0]); - r.top = (LONG)(clipRect->y - renderTargetOffset[1]); - r.right = (LONG)(clipRect->x - renderTargetOffset[0] + clipRect->width); - r.bottom = (LONG)(clipRect->y - renderTargetOffset[1] + clipRect->height); - } else { - if (useIntermediate) { + if (clipRect || useIntermediate) { + RECT r; + device()->GetScissorRect(&oldClipRect); + if (clipRect) { + r.left = (LONG)(clipRect->x - renderTargetOffset[0]); + r.top = (LONG)(clipRect->y - renderTargetOffset[1]); + r.right = (LONG)(clipRect->x - renderTargetOffset[0] + clipRect->width); + r.bottom = (LONG)(clipRect->y - renderTargetOffset[1] + clipRect->height); + } else { r.left = 0; r.top = 0; + r.right = visibleRect.width; + r.bottom = visibleRect.height; + } + + nsRefPtr<IDirect3DSurface9> renderSurface; + device()->GetRenderTarget(0, getter_AddRefs(renderSurface)); + + D3DSURFACE_DESC desc; + renderSurface->GetDesc(&desc); + + if (!useIntermediate) { + // Intersect with current clip rect. + r.left = NS_MAX<PRInt32>(oldClipRect.left, r.left); + r.right = NS_MIN<PRInt32>(oldClipRect.right, r.right); + r.top = NS_MAX<PRInt32>(oldClipRect.top, r.top); + r.bottom = NS_MAX<PRInt32>(oldClipRect.bottom, r.bottom); } else { - r.left = visibleRect.x; - r.top = visibleRect.y; + // > 0 is implied during the intersection when useIntermediate == true; + r.left = NS_MAX<LONG>(0, r.left); + r.top = NS_MAX<LONG>(0, r.top); } - r.right = r.left + visibleRect.width; - r.bottom = r.top + visibleRect.height; + r.bottom = NS_MIN<LONG>(r.bottom, desc.Height); + r.right = NS_MIN<LONG>(r.right, desc.Width); + + device()->SetScissorRect(&r); } - nsRefPtr<IDirect3DSurface9> renderSurface; - device()->GetRenderTarget(0, getter_AddRefs(renderSurface)); - - D3DSURFACE_DESC desc; - renderSurface->GetDesc(&desc); + if (!useIntermediate) { + layerToRender->RenderLayer(opacity, transform); + } else { + layerToRender->RenderLayer(1.0, gfx3DMatrix()); + } - r.left = NS_MAX<LONG>(0, r.left); - r.top = NS_MAX<LONG>(0, r.top); - r.bottom = NS_MIN<LONG>(r.bottom, desc.Height); - r.right = NS_MIN<LONG>(r.right, desc.Width); + if (clipRect || useIntermediate) { + device()->SetScissorRect(&oldClipRect); + } - device()->SetScissorRect(&r); - - layerToRender->RenderLayer(); Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling(); layerToRender = nextSibling ? static_cast<LayerD3D9*>(nextSibling-> ImplData()) : nsnull; } if (useIntermediate) { device()->SetRenderTarget(0, previousRenderTarget); - device()->SetScissorRect(&oldClipRect); device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); device()->SetVertexShaderConstantF(CBvLayerQuad, ShaderConstantRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height), 1); - device()->SetVertexShaderConstantF(CBmLayerTransform, &mTransform._11, 4); + device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); float opacityVector[4]; /* * We always upload a 4 component float, but the shader will use only the * first component since it's declared as a 'float'. */ opacityVector[0] = opacity; device()->SetPixelShaderConstantF(CBfLayerOpacity, opacityVector, 1); @@ -256,10 +272,37 @@ void ContainerLayerD3D9::LayerManagerDestroyed() { while (mFirstChild) { GetFirstChildD3D9()->LayerManagerDestroyed(); RemoveChild(mFirstChild); } } +bool +ContainerLayerD3D9::ShouldUseIntermediate(float aOpacity, + const gfx3DMatrix &aMatrix) +{ + if (aOpacity == 1.0f && aMatrix.IsIdentity()) { + return false; + } + + Layer *firstChild = GetFirstChild(); + + if (!firstChild || (!firstChild->GetNextSibling() && + !firstChild->GetClipRect())) { + // If we forward our transform to a child without using an intermediate, + // we need to be sure that child does not have a clip rect, since its clip + // rect would be applied after our transform. + return false; + } + + if (aMatrix.IsIdentity() && (!firstChild || !firstChild->GetNextSibling())) { + // If there's no transforms applied and a single child, opacity can always + // be forwarded to our only child. + return false; + } + + return true; +} + } /* layers */ } /* mozilla */
--- a/gfx/layers/d3d9/ContainerLayerD3D9.h +++ b/gfx/layers/d3d9/ContainerLayerD3D9.h @@ -60,17 +60,21 @@ public: /* LayerD3D9 implementation */ Layer* GetLayer(); LayerD3D9* GetFirstChildD3D9(); PRBool IsEmpty(); - void RenderLayer(); + void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); virtual void LayerManagerDestroyed(); + +private: + bool ShouldUseIntermediate(float aOpacity, + const gfx3DMatrix &aMatrix); }; } /* layers */ } /* mozilla */ #endif /* GFX_CONTAINERLAYERD3D9_H */
--- a/gfx/layers/d3d9/ImageLayerD3D9.cpp +++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp @@ -143,17 +143,17 @@ ImageContainerD3D9::SetLayerManager(Laye Layer* ImageLayerD3D9::GetLayer() { return this; } void -ImageLayerD3D9::RenderLayer() +ImageLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) { if (!GetContainer()) { return; } nsRefPtr<Image> image = GetContainer()->GetCurrentImage(); if (image->GetFormat() == Image::PLANAR_YCBCR) { @@ -167,24 +167,25 @@ ImageLayerD3D9::RenderLayer() device()->SetVertexShaderConstantF(CBvLayerQuad, ShaderConstantRect(0, 0, yuvImage->mSize.width, yuvImage->mSize.height), 1); - device()->SetVertexShaderConstantF(CBmLayerTransform, &mTransform._11, 4); + gfx3DMatrix transform = mTransform * aTransform; + device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); float opacity[4]; /* * We always upload a 4 component float, but the shader will * only use the the first component since it's declared as a 'float'. */ - opacity[0] = GetOpacity(); + opacity[0] = GetOpacity() * aOpacity; device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1); mD3DManager->SetShaderMode(DeviceManagerD3D9::YCBCRLAYER); /* * Send 3d control data and metadata */ if (mD3DManager->Is3DEnabled() && mD3DManager->GetNv3DVUtils()) { @@ -215,24 +216,25 @@ ImageLayerD3D9::RenderLayer() device()->SetVertexShaderConstantF(CBvLayerQuad, ShaderConstantRect(0, 0, cairoImage->mSize.width, cairoImage->mSize.height), 1); - device()->SetVertexShaderConstantF(CBmLayerTransform, &mTransform._11, 4); + gfx3DMatrix transform = mTransform * aTransform; + device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); float opacity[4]; /* * We always upload a 4 component float, but the shader will * only use the the first component since it's declared as a 'float'. */ - opacity[0] = GetOpacity(); + opacity[0] = GetOpacity() * aOpacity; device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1); mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER); device()->SetTexture(0, cairoImage->mTexture); device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); } }
--- a/gfx/layers/d3d9/ImageLayerD3D9.h +++ b/gfx/layers/d3d9/ImageLayerD3D9.h @@ -82,17 +82,17 @@ public: , LayerD3D9(aManager) { mImplData = static_cast<LayerD3D9*>(this); } // LayerD3D9 Implementation virtual Layer* GetLayer(); - virtual void RenderLayer(); + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); }; class THEBES_API ImageD3D9 { public: virtual already_AddRefed<gfxASurface> GetAsSurface() = 0; };
--- a/gfx/layers/d3d9/LayerManagerD3D9.cpp +++ b/gfx/layers/d3d9/LayerManagerD3D9.cpp @@ -293,17 +293,17 @@ LayerManagerD3D9::Render() r.bottom = (LONG)(clipRect->y + clipRect->height); } else { r.left = r.top = 0; r.right = rect.width; r.bottom = rect.height; } device()->SetScissorRect(&r); - static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer(); + static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer(1.0, gfx3DMatrix()); } device()->EndScene(); if (!mTarget) { const nsIntRect *r; for (nsIntRegionRectIterator iter(mClippingRegion); (r = iter.Next()) != nsnull;) {
--- a/gfx/layers/d3d9/LayerManagerD3D9.h +++ b/gfx/layers/d3d9/LayerManagerD3D9.h @@ -246,17 +246,17 @@ public: LayerD3D9(LayerManagerD3D9 *aManager); virtual LayerD3D9 *GetFirstChildD3D9() { return nsnull; } void SetFirstChild(LayerD3D9 *aParent); virtual Layer* GetLayer() = 0; - virtual void RenderLayer() = 0; + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) = 0; /* This function may be used on device resets to clear all VRAM resources * that a layer might be using. */ virtual void CleanResources() {} IDirect3DDevice9 *device() const { return mD3DManager->device(); }
--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp +++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp @@ -167,17 +167,17 @@ ThebesLayerD3D9::SetVisibleRegion(const void ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion) { mValidRegion.Sub(mValidRegion, aRegion); } void -ThebesLayerD3D9::RenderLayer() +ThebesLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) { if (mVisibleRegion.IsEmpty()) { return; } nsIntRect visibleRect = mVisibleRegion.GetBounds(); // We differentiate between these formats since D3D9 will only allow us to @@ -220,24 +220,25 @@ ThebesLayerD3D9::RenderLayer() nsIntRegion region; region.Sub(mVisibleRegion, mValidRegion); DrawRegion(region); mValidRegion = mVisibleRegion; } - device()->SetVertexShaderConstantF(CBmLayerTransform, &mTransform._11, 4); + gfx3DMatrix transform = mTransform * aTransform; + device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); 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] = GetOpacity(); + opacity[0] = GetOpacity() * aOpacity; device()->SetPixelShaderConstantF(0, opacity, 1); #ifdef CAIRO_HAS_D2D_SURFACE if (mD2DSurface && CanUseOpaqueSurface()) { mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER); } else #endif mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER);
--- a/gfx/layers/d3d9/ThebesLayerD3D9.h +++ b/gfx/layers/d3d9/ThebesLayerD3D9.h @@ -56,17 +56,17 @@ public: void SetVisibleRegion(const nsIntRegion& aRegion); /* ThebesLayer implementation */ void InvalidateRegion(const nsIntRegion& aRegion); /* LayerD3D9 implementation */ Layer* GetLayer(); virtual PRBool IsEmpty(); - virtual void RenderLayer(); + virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform); virtual void CleanResources(); virtual void LayerManagerDestroyed(); private: /* * D3D9 texture */ nsRefPtr<IDirect3DTexture9> mTexture;