author | Oleg Romashin <romaxa@gmail.com> |
Tue, 30 Nov 2010 08:02:46 +0200 | |
changeset 59559 | ab173acf8a1f751ba485980e032d4fe18be4b05d |
parent 59558 | d538a677628e71f1de7de056a93d195a08f6112b |
child 59560 | 722ffb1a0920773fc92adac27244e13f3c5a1c95 |
push id | 17664 |
push user | romaxa@gmail.com |
push date | Tue, 21 Dec 2010 18:45:33 +0000 |
treeherder | mozilla-central@722ffb1a0920 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc, approval2.0 |
bugs | 607653 |
milestone | 2.0b9pre |
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/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -327,17 +327,19 @@ ContainerLayer::DefaultComputeEffectiveT mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), &residual); PRBool useIntermediateSurface; float opacity = GetEffectiveOpacity(); if (opacity != 1.0f && HasMultipleChildren()) { useIntermediateSurface = PR_TRUE; } else { useIntermediateSurface = PR_FALSE; - if (!mEffectiveTransform.IsIdentity()) { + gfxMatrix contTransform; + if (!mEffectiveTransform.Is2D(&contTransform) || + !contTransform.PreservesAxisAlignedRectangles()) { for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) { const nsIntRect *clipRect = child->GetEffectiveClipRect(); /* We can't (easily) forward our transform to children with a non-empty clip * rect since it would need to be adjusted for the transform. * TODO: This is easily solvable for translation/scaling transforms. */ if (clipRect && !clipRect->IsEmpty() && !child->GetVisibleRegion().IsEmpty()) { useIntermediateSurface = PR_TRUE;
--- a/gfx/layers/d3d10/ContainerLayerD3D10.cpp +++ b/gfx/layers/d3d10/ContainerLayerD3D10.cpp @@ -166,16 +166,17 @@ ContainerLayerD3D10::RenderLayer() nsRefPtr<ID3D10RenderTargetView> previousRTView; nsRefPtr<ID3D10Texture2D> renderTexture; nsRefPtr<ID3D10RenderTargetView> rtView; float previousRenderTargetOffset[2]; nsIntSize previousViewportSize; gfx3DMatrix oldViewMatrix; + gfxMatrix contTransform; if (useIntermediate) { device()->OMGetRenderTargets(1, getter_AddRefs(previousRTView), NULL); D3D10_TEXTURE2D_DESC desc; memset(&desc, 0, sizeof(D3D10_TEXTURE2D_DESC)); desc.ArraySize = 1; desc.MipLevels = 1; desc.Width = visibleRect.width; @@ -198,16 +199,22 @@ ContainerLayerD3D10::RenderLayer() renderTargetOffset[0] = (float)visibleRect.x; renderTargetOffset[1] = (float)visibleRect.y; effect()->GetVariableByName("vRenderTargetOffset")-> SetRawValue(renderTargetOffset, 0, 8); previousViewportSize = mD3DManager->GetViewport(); mD3DManager->SetViewport(nsIntSize(visibleRect.Size())); + } else { +#ifdef DEBUG + PRBool is2d = +#endif + GetEffectiveTransform().Is2D(&contTransform); + NS_ASSERTION(is2d, "Transform must be 2D"); } /* * Render this container's contents. */ for (LayerD3D10* layerToRender = GetFirstChildD3D10(); layerToRender != nsnull; layerToRender = GetNextSiblingD3D10(layerToRender)) { @@ -234,16 +241,34 @@ ContainerLayerD3D10::RenderLayer() r.left = 0; r.top = 0; r.right = visibleRect.width; r.bottom = visibleRect.height; } D3D10_RECT d3drect; if (!useIntermediate) { + if (clipRect) { + gfxRect cliprect(r.left, r.top, r.right - r.left, r.bottom - r.top); + gfxRect trScissor = contTransform.TransformBounds(cliprect); + trScissor.Round(); + nsIntRect trIntScissor; + if (gfxUtils::GfxRectToIntRect(trScissor, &trIntScissor)) { + r.left = trIntScissor.x; + r.top = trIntScissor.y; + r.right = trIntScissor.XMost(); + r.bottom = trIntScissor.YMost(); + } else { + r.left = 0; + r.top = 0; + r.right = visibleRect.width; + r.bottom = visibleRect.height; + clipRect = nsnull; + } + } // Scissor rect should be an intersection of the old and current scissor. r.left = NS_MAX<PRInt32>(oldScissor.left, r.left); r.right = NS_MIN<PRInt32>(oldScissor.right, r.right); r.top = NS_MAX<PRInt32>(oldScissor.top, r.top); r.bottom = NS_MIN<PRInt32>(oldScissor.bottom, r.bottom); } if (r.left >= r.right || r.top >= r.bottom) {
--- a/gfx/layers/d3d9/ContainerLayerD3D9.cpp +++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp @@ -161,16 +161,17 @@ ContainerLayerD3D9::RenderLayer() float previousRenderTargetOffset[4]; RECT oldClipRect; float renderTargetOffset[] = { 0, 0, 0, 0 }; float oldViewMatrix[4][4]; nsIntRect visibleRect = mVisibleRegion.GetBounds(); PRBool useIntermediate = UseIntermediateSurface(); + gfxMatrix contTransform; if (useIntermediate) { device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget)); 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)); @@ -188,16 +189,22 @@ ContainerLayerD3D9::RenderLayer() */ viewMatrix._11 = 2.0f / visibleRect.width; viewMatrix._22 = -2.0f / visibleRect.height; viewMatrix._41 = -1.0f; viewMatrix._42 = 1.0f; device()->GetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); device()->SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4); + } else { +#ifdef DEBUG + PRBool is2d = +#endif + GetEffectiveTransform().Is2D(&contTransform); + NS_ASSERTION(is2d, "Transform must be 2D"); } /* * Render this container's contents. */ for (LayerD3D9* layerToRender = GetFirstChildD3D9(); layerToRender != nsnull; layerToRender = GetNextSiblingD3D9(layerToRender)) { @@ -225,16 +232,35 @@ ContainerLayerD3D9::RenderLayer() nsRefPtr<IDirect3DSurface9> renderSurface; device()->GetRenderTarget(0, getter_AddRefs(renderSurface)); D3DSURFACE_DESC desc; renderSurface->GetDesc(&desc); if (!useIntermediate) { + // Transform clip rect + if (clipRect) { + gfxRect cliprect(r.left, r.top, r.right - r.left, r.bottom - r.top); + gfxRect trScissor = contTransform.TransformBounds(cliprect); + trScissor.Round(); + nsIntRect trIntScissor; + if (gfxUtils::GfxRectToIntRect(trScissor, &trIntScissor)) { + r.left = trIntScissor.x; + r.top = trIntScissor.y; + r.right = trIntScissor.XMost(); + r.bottom = trIntScissor.YMost(); + } else { + r.left = 0; + r.top = 0; + r.right = visibleRect.width; + r.bottom = visibleRect.height; + clipRect = nsnull; + } + } // 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_MIN<PRInt32>(oldClipRect.bottom, r.bottom); } else { // > 0 is implied during the intersection when useIntermediate == true; r.left = NS_MAX<LONG>(0, r.left);
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp +++ b/gfx/layers/opengl/ContainerLayerOGL.cpp @@ -155,32 +155,38 @@ ContainerRender(Container* aContainer, nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); nsIntRect cachedScissor = aContainer->gl()->ScissorRect(); aContainer->gl()->PushScissorRect(); float opacity = aContainer->GetEffectiveOpacity(); const gfx3DMatrix& transform = aContainer->GetEffectiveTransform(); bool needsFramebuffer = aContainer->UseIntermediateSurface(); + gfxMatrix contTransform; if (needsFramebuffer) { aManager->CreateFBOWithTexture(visibleRect.width, visibleRect.height, &frameBuffer, &containerSurface); childOffset.x = visibleRect.x; childOffset.y = visibleRect.y; aContainer->gl()->PushViewportRect(); aManager->SetupPipeline(visibleRect.width, visibleRect.height); aContainer->gl()->fScissor(0, 0, visibleRect.width, visibleRect.height); aContainer->gl()->fClearColor(0.0, 0.0, 0.0, 0.0); aContainer->gl()->fClear(LOCAL_GL_COLOR_BUFFER_BIT); } else { frameBuffer = aPreviousFrameBuffer; +#ifdef DEBUG + PRBool is2d = +#endif + transform.Is2D(&contTransform); + NS_ASSERTION(is2d, "Transform must be 2D"); } /** * Render this container's contents. */ for (LayerOGL* layerToRender = aContainer->GetFirstChildOGL(); layerToRender != nsnull; layerToRender = GetNextSibling(layerToRender)) { @@ -192,16 +198,24 @@ ContainerRender(Container* aContainer, nsIntRect scissorRect(visibleRect); const nsIntRect *clipRect = layerToRender->GetLayer()->GetEffectiveClipRect(); if (clipRect) { if (clipRect->IsEmpty()) { continue; } scissorRect = *clipRect; + if (!needsFramebuffer) { + gfxRect r(scissorRect.x, scissorRect.y, scissorRect.width, scissorRect.height); + gfxRect trScissor = contTransform.TransformBounds(r); + trScissor.Round(); + if (!gfxUtils::GfxRectToIntRect(trScissor, &scissorRect)) { + scissorRect = visibleRect; + } + } } if (needsFramebuffer) { scissorRect.MoveBy(- visibleRect.TopLeft()); } else { if (!aPreviousFrameBuffer) { /** * glScissor coordinates are oriented with 0,0 being at the bottom left,