1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,218 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "ContainerLayerD3D9.h" 1.10 + 1.11 +#include "ThebesLayerD3D9.h" 1.12 +#include "ReadbackProcessor.h" 1.13 + 1.14 +using namespace mozilla::gfx; 1.15 + 1.16 +namespace mozilla { 1.17 +namespace layers { 1.18 + 1.19 +ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager) 1.20 + : ContainerLayer(aManager, nullptr) 1.21 + , LayerD3D9(aManager) 1.22 +{ 1.23 + mImplData = static_cast<LayerD3D9*>(this); 1.24 +} 1.25 + 1.26 +ContainerLayerD3D9::~ContainerLayerD3D9() 1.27 +{ 1.28 + while (mFirstChild) { 1.29 + RemoveChild(mFirstChild); 1.30 + } 1.31 +} 1.32 + 1.33 +Layer* 1.34 +ContainerLayerD3D9::GetLayer() 1.35 +{ 1.36 + return this; 1.37 +} 1.38 + 1.39 +LayerD3D9* 1.40 +ContainerLayerD3D9::GetFirstChildD3D9() 1.41 +{ 1.42 + if (!mFirstChild) { 1.43 + return nullptr; 1.44 + } 1.45 + return static_cast<LayerD3D9*>(mFirstChild->ImplData()); 1.46 +} 1.47 + 1.48 +void 1.49 +ContainerLayerD3D9::RenderLayer() 1.50 +{ 1.51 + nsRefPtr<IDirect3DSurface9> previousRenderTarget; 1.52 + nsRefPtr<IDirect3DTexture9> renderTexture; 1.53 + float previousRenderTargetOffset[4]; 1.54 + float renderTargetOffset[] = { 0, 0, 0, 0 }; 1.55 + float oldViewMatrix[4][4]; 1.56 + 1.57 + RECT containerD3D9ClipRect; 1.58 + device()->GetScissorRect(&containerD3D9ClipRect); 1.59 + // Convert scissor to an nsIntRect. RECT's are exclusive on the bottom and 1.60 + // right values. 1.61 + nsIntRect oldScissor(containerD3D9ClipRect.left, 1.62 + containerD3D9ClipRect.top, 1.63 + containerD3D9ClipRect.right - containerD3D9ClipRect.left, 1.64 + containerD3D9ClipRect.bottom - containerD3D9ClipRect.top); 1.65 + 1.66 + ReadbackProcessor readback; 1.67 + readback.BuildUpdates(this); 1.68 + 1.69 + nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds(); 1.70 + bool useIntermediate = UseIntermediateSurface(); 1.71 + 1.72 + mSupportsComponentAlphaChildren = false; 1.73 + if (useIntermediate) { 1.74 + nsRefPtr<IDirect3DSurface9> renderSurface; 1.75 + if (!mD3DManager->CompositingDisabled()) { 1.76 + device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget)); 1.77 + HRESULT hr = device()->CreateTexture(visibleRect.width, visibleRect.height, 1, 1.78 + D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, 1.79 + D3DPOOL_DEFAULT, getter_AddRefs(renderTexture), 1.80 + nullptr); 1.81 + if (FAILED(hr)) { 1.82 + ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"), 1.83 + hr); 1.84 + return; 1.85 + } 1.86 + 1.87 + nsRefPtr<IDirect3DSurface9> renderSurface; 1.88 + renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface)); 1.89 + device()->SetRenderTarget(0, renderSurface); 1.90 + } 1.91 + 1.92 + if (mVisibleRegion.GetNumRects() == 1 && 1.93 + (GetContentFlags() & CONTENT_OPAQUE)) { 1.94 + // don't need a background, we're going to paint all opaque stuff 1.95 + mSupportsComponentAlphaChildren = true; 1.96 + } else { 1.97 + Matrix4x4 transform3D = GetEffectiveTransform(); 1.98 + Matrix transform; 1.99 + // If we have an opaque ancestor layer, then we can be sure that 1.100 + // all the pixels we draw into are either opaque already or will be 1.101 + // covered by something opaque. Otherwise copying up the background is 1.102 + // not safe. 1.103 + HRESULT hr = E_FAIL; 1.104 + if (HasOpaqueAncestorLayer(this) && 1.105 + transform3D.Is2D(&transform) && !ThebesMatrix(transform).HasNonIntegerTranslation()) { 1.106 + // Copy background up from below 1.107 + RECT dest = { 0, 0, visibleRect.width, visibleRect.height }; 1.108 + RECT src = dest; 1.109 + ::OffsetRect(&src, 1.110 + visibleRect.x + int32_t(transform._31), 1.111 + visibleRect.y + int32_t(transform._32)); 1.112 + if (!mD3DManager->CompositingDisabled()) { 1.113 + hr = device()-> 1.114 + StretchRect(previousRenderTarget, &src, renderSurface, &dest, D3DTEXF_NONE); 1.115 + } 1.116 + } 1.117 + if (hr == S_OK) { 1.118 + mSupportsComponentAlphaChildren = true; 1.119 + } else if (!mD3DManager->CompositingDisabled()) { 1.120 + device()-> 1.121 + Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0); 1.122 + } 1.123 + } 1.124 + 1.125 + device()-> 1.126 + GetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); 1.127 + renderTargetOffset[0] = (float)visibleRect.x; 1.128 + renderTargetOffset[1] = (float)visibleRect.y; 1.129 + device()-> 1.130 + SetVertexShaderConstantF(CBvRenderTargetOffset, renderTargetOffset, 1); 1.131 + 1.132 + gfx3DMatrix viewMatrix; 1.133 + /* 1.134 + * Matrix to transform to viewport space ( <-1.0, 1.0> topleft, 1.135 + * <1.0, -1.0> bottomright) 1.136 + */ 1.137 + viewMatrix._11 = 2.0f / visibleRect.width; 1.138 + viewMatrix._22 = -2.0f / visibleRect.height; 1.139 + viewMatrix._41 = -1.0f; 1.140 + viewMatrix._42 = 1.0f; 1.141 + 1.142 + device()-> 1.143 + GetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); 1.144 + device()-> 1.145 + SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4); 1.146 + } else { 1.147 + mSupportsComponentAlphaChildren = 1.148 + (GetContentFlags() & CONTENT_OPAQUE) || 1.149 + (mParent && 1.150 + mParent->SupportsComponentAlphaChildren()); 1.151 + } 1.152 + 1.153 + nsAutoTArray<Layer*, 12> children; 1.154 + SortChildrenBy3DZOrder(children); 1.155 + 1.156 + /* 1.157 + * Render this container's contents. 1.158 + */ 1.159 + for (uint32_t i = 0; i < children.Length(); i++) { 1.160 + LayerD3D9* layerToRender = static_cast<LayerD3D9*>(children.ElementAt(i)->ImplData()); 1.161 + 1.162 + if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) { 1.163 + continue; 1.164 + } 1.165 + 1.166 + nsIntRect scissorRect = 1.167 + layerToRender->GetLayer()->CalculateScissorRect(oldScissor, nullptr); 1.168 + if (scissorRect.IsEmpty()) { 1.169 + continue; 1.170 + } 1.171 + 1.172 + RECT d3drect; 1.173 + d3drect.left = scissorRect.x; 1.174 + d3drect.top = scissorRect.y; 1.175 + d3drect.right = scissorRect.x + scissorRect.width; 1.176 + d3drect.bottom = scissorRect.y + scissorRect.height; 1.177 + device()->SetScissorRect(&d3drect); 1.178 + 1.179 + if (layerToRender->GetLayer()->GetType() == TYPE_THEBES) { 1.180 + static_cast<ThebesLayerD3D9*>(layerToRender)->RenderThebesLayer(&readback); 1.181 + } else { 1.182 + layerToRender->RenderLayer(); 1.183 + } 1.184 + } 1.185 + 1.186 + if (useIntermediate && !mD3DManager->CompositingDisabled()) { 1.187 + device()->SetRenderTarget(0, previousRenderTarget); 1.188 + device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); 1.189 + device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); 1.190 + 1.191 + device()->SetVertexShaderConstantF(CBvLayerQuad, 1.192 + ShaderConstantRect(visibleRect.x, 1.193 + visibleRect.y, 1.194 + visibleRect.width, 1.195 + visibleRect.height), 1.196 + 1); 1.197 + 1.198 + SetShaderTransformAndOpacity(); 1.199 + mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER, 1.200 + GetMaskLayer(), 1.201 + GetTransform().CanDraw2D()); 1.202 + 1.203 + device()->SetTexture(0, renderTexture); 1.204 + device()->SetScissorRect(&containerD3D9ClipRect); 1.205 + device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 1.206 + } else { 1.207 + device()->SetScissorRect(&containerD3D9ClipRect); 1.208 + } 1.209 +} 1.210 + 1.211 +void 1.212 +ContainerLayerD3D9::LayerManagerDestroyed() 1.213 +{ 1.214 + while (mFirstChild) { 1.215 + GetFirstChildD3D9()->LayerManagerDestroyed(); 1.216 + RemoveChild(mFirstChild); 1.217 + } 1.218 +} 1.219 + 1.220 +} /* layers */ 1.221 +} /* mozilla */