Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "ContainerLayerD3D9.h"
8 #include "ThebesLayerD3D9.h"
9 #include "ReadbackProcessor.h"
11 using namespace mozilla::gfx;
13 namespace mozilla {
14 namespace layers {
16 ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager)
17 : ContainerLayer(aManager, nullptr)
18 , LayerD3D9(aManager)
19 {
20 mImplData = static_cast<LayerD3D9*>(this);
21 }
23 ContainerLayerD3D9::~ContainerLayerD3D9()
24 {
25 while (mFirstChild) {
26 RemoveChild(mFirstChild);
27 }
28 }
30 Layer*
31 ContainerLayerD3D9::GetLayer()
32 {
33 return this;
34 }
36 LayerD3D9*
37 ContainerLayerD3D9::GetFirstChildD3D9()
38 {
39 if (!mFirstChild) {
40 return nullptr;
41 }
42 return static_cast<LayerD3D9*>(mFirstChild->ImplData());
43 }
45 void
46 ContainerLayerD3D9::RenderLayer()
47 {
48 nsRefPtr<IDirect3DSurface9> previousRenderTarget;
49 nsRefPtr<IDirect3DTexture9> renderTexture;
50 float previousRenderTargetOffset[4];
51 float renderTargetOffset[] = { 0, 0, 0, 0 };
52 float oldViewMatrix[4][4];
54 RECT containerD3D9ClipRect;
55 device()->GetScissorRect(&containerD3D9ClipRect);
56 // Convert scissor to an nsIntRect. RECT's are exclusive on the bottom and
57 // right values.
58 nsIntRect oldScissor(containerD3D9ClipRect.left,
59 containerD3D9ClipRect.top,
60 containerD3D9ClipRect.right - containerD3D9ClipRect.left,
61 containerD3D9ClipRect.bottom - containerD3D9ClipRect.top);
63 ReadbackProcessor readback;
64 readback.BuildUpdates(this);
66 nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds();
67 bool useIntermediate = UseIntermediateSurface();
69 mSupportsComponentAlphaChildren = false;
70 if (useIntermediate) {
71 nsRefPtr<IDirect3DSurface9> renderSurface;
72 if (!mD3DManager->CompositingDisabled()) {
73 device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
74 HRESULT hr = device()->CreateTexture(visibleRect.width, visibleRect.height, 1,
75 D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
76 D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
77 nullptr);
78 if (FAILED(hr)) {
79 ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"),
80 hr);
81 return;
82 }
84 nsRefPtr<IDirect3DSurface9> renderSurface;
85 renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
86 device()->SetRenderTarget(0, renderSurface);
87 }
89 if (mVisibleRegion.GetNumRects() == 1 &&
90 (GetContentFlags() & CONTENT_OPAQUE)) {
91 // don't need a background, we're going to paint all opaque stuff
92 mSupportsComponentAlphaChildren = true;
93 } else {
94 Matrix4x4 transform3D = GetEffectiveTransform();
95 Matrix transform;
96 // If we have an opaque ancestor layer, then we can be sure that
97 // all the pixels we draw into are either opaque already or will be
98 // covered by something opaque. Otherwise copying up the background is
99 // not safe.
100 HRESULT hr = E_FAIL;
101 if (HasOpaqueAncestorLayer(this) &&
102 transform3D.Is2D(&transform) && !ThebesMatrix(transform).HasNonIntegerTranslation()) {
103 // Copy background up from below
104 RECT dest = { 0, 0, visibleRect.width, visibleRect.height };
105 RECT src = dest;
106 ::OffsetRect(&src,
107 visibleRect.x + int32_t(transform._31),
108 visibleRect.y + int32_t(transform._32));
109 if (!mD3DManager->CompositingDisabled()) {
110 hr = device()->
111 StretchRect(previousRenderTarget, &src, renderSurface, &dest, D3DTEXF_NONE);
112 }
113 }
114 if (hr == S_OK) {
115 mSupportsComponentAlphaChildren = true;
116 } else if (!mD3DManager->CompositingDisabled()) {
117 device()->
118 Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0);
119 }
120 }
122 device()->
123 GetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1);
124 renderTargetOffset[0] = (float)visibleRect.x;
125 renderTargetOffset[1] = (float)visibleRect.y;
126 device()->
127 SetVertexShaderConstantF(CBvRenderTargetOffset, renderTargetOffset, 1);
129 gfx3DMatrix viewMatrix;
130 /*
131 * Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
132 * <1.0, -1.0> bottomright)
133 */
134 viewMatrix._11 = 2.0f / visibleRect.width;
135 viewMatrix._22 = -2.0f / visibleRect.height;
136 viewMatrix._41 = -1.0f;
137 viewMatrix._42 = 1.0f;
139 device()->
140 GetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4);
141 device()->
142 SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4);
143 } else {
144 mSupportsComponentAlphaChildren =
145 (GetContentFlags() & CONTENT_OPAQUE) ||
146 (mParent &&
147 mParent->SupportsComponentAlphaChildren());
148 }
150 nsAutoTArray<Layer*, 12> children;
151 SortChildrenBy3DZOrder(children);
153 /*
154 * Render this container's contents.
155 */
156 for (uint32_t i = 0; i < children.Length(); i++) {
157 LayerD3D9* layerToRender = static_cast<LayerD3D9*>(children.ElementAt(i)->ImplData());
159 if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
160 continue;
161 }
163 nsIntRect scissorRect =
164 layerToRender->GetLayer()->CalculateScissorRect(oldScissor, nullptr);
165 if (scissorRect.IsEmpty()) {
166 continue;
167 }
169 RECT d3drect;
170 d3drect.left = scissorRect.x;
171 d3drect.top = scissorRect.y;
172 d3drect.right = scissorRect.x + scissorRect.width;
173 d3drect.bottom = scissorRect.y + scissorRect.height;
174 device()->SetScissorRect(&d3drect);
176 if (layerToRender->GetLayer()->GetType() == TYPE_THEBES) {
177 static_cast<ThebesLayerD3D9*>(layerToRender)->RenderThebesLayer(&readback);
178 } else {
179 layerToRender->RenderLayer();
180 }
181 }
183 if (useIntermediate && !mD3DManager->CompositingDisabled()) {
184 device()->SetRenderTarget(0, previousRenderTarget);
185 device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1);
186 device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4);
188 device()->SetVertexShaderConstantF(CBvLayerQuad,
189 ShaderConstantRect(visibleRect.x,
190 visibleRect.y,
191 visibleRect.width,
192 visibleRect.height),
193 1);
195 SetShaderTransformAndOpacity();
196 mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER,
197 GetMaskLayer(),
198 GetTransform().CanDraw2D());
200 device()->SetTexture(0, renderTexture);
201 device()->SetScissorRect(&containerD3D9ClipRect);
202 device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
203 } else {
204 device()->SetScissorRect(&containerD3D9ClipRect);
205 }
206 }
208 void
209 ContainerLayerD3D9::LayerManagerDestroyed()
210 {
211 while (mFirstChild) {
212 GetFirstChildD3D9()->LayerManagerDestroyed();
213 RemoveChild(mFirstChild);
214 }
215 }
217 } /* layers */
218 } /* mozilla */