gfx/layers/d3d10/ContainerLayerD3D10.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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: 2 -*-
     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 "ContainerLayerD3D10.h"
     8 #include "ThebesLayerD3D10.h"
     9 #include "ReadbackProcessor.h"
    11 using namespace mozilla::gfx;
    13 namespace mozilla {
    14 namespace layers {
    16 ContainerLayerD3D10::ContainerLayerD3D10(LayerManagerD3D10 *aManager)
    17   : ContainerLayer(aManager, nullptr)
    18   , LayerD3D10(aManager)
    19 {
    20   mImplData = static_cast<LayerD3D10*>(this);
    21 }
    23 ContainerLayerD3D10::~ContainerLayerD3D10()
    24 {
    25   while (mFirstChild) {
    26     RemoveChild(mFirstChild);
    27   }
    28 }
    30 Layer*
    31 ContainerLayerD3D10::GetLayer()
    32 {
    33   return this;
    34 }
    36 LayerD3D10*
    37 ContainerLayerD3D10::GetFirstChildD3D10()
    38 {
    39   if (!mFirstChild) {
    40     return nullptr;
    41   }
    42   return static_cast<LayerD3D10*>(mFirstChild->ImplData());
    43 }
    45 static inline LayerD3D10*
    46 GetNextSiblingD3D10(LayerD3D10* aLayer)
    47 {
    48    Layer* layer = aLayer->GetLayer()->GetNextSibling();
    49    return layer ? static_cast<LayerD3D10*>(layer->
    50                                            ImplData())
    51                 : nullptr;
    52 }
    54 void
    55 ContainerLayerD3D10::RenderLayer()
    56 {
    57   float renderTargetOffset[] = { 0, 0 };
    59   nsIntRect visibleRect = mVisibleRegion.GetBounds();
    60   float opacity = GetEffectiveOpacity();
    61   bool useIntermediate = UseIntermediateSurface();
    63   nsRefPtr<ID3D10RenderTargetView> previousRTView;
    64   nsRefPtr<ID3D10Texture2D> renderTexture;
    65   nsRefPtr<ID3D10RenderTargetView> rtView;
    66   float previousRenderTargetOffset[2];
    67   nsIntSize previousViewportSize;
    69   gfx3DMatrix oldViewMatrix;
    71   if (useIntermediate) {
    72     device()->OMGetRenderTargets(1, getter_AddRefs(previousRTView), nullptr);
    74     D3D10_TEXTURE2D_DESC desc;
    75     memset(&desc, 0, sizeof(D3D10_TEXTURE2D_DESC));
    76     desc.ArraySize = 1;
    77     desc.MipLevels = 1;
    78     desc.Width = visibleRect.width;
    79     desc.Height = visibleRect.height;
    80     desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
    81     desc.SampleDesc.Count = 1;
    82     desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    83     HRESULT hr;
    84     hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(renderTexture));
    86     if (FAILED(hr)) {
    87       LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("Failed to create new texture for ContainerLayerD3D10!"), 
    88                                        hr);
    89       return;
    90     }
    92     hr = device()->CreateRenderTargetView(renderTexture, nullptr, getter_AddRefs(rtView));
    93     NS_ASSERTION(SUCCEEDED(hr), "Failed to create render target view for ContainerLayerD3D10!");
    95     effect()->GetVariableByName("vRenderTargetOffset")->
    96       GetRawValue(previousRenderTargetOffset, 0, 8);
    98     previousViewportSize = mD3DManager->GetViewport();
   100     if (mVisibleRegion.GetNumRects() != 1 || !(GetContentFlags() & CONTENT_OPAQUE)) {
   101       Matrix4x4 transform3D = GetEffectiveTransform();
   102       Matrix transform;
   103       // If we have an opaque ancestor layer, then we can be sure that
   104       // all the pixels we draw into are either opaque already or will be
   105       // covered by something opaque. Otherwise copying up the background is
   106       // not safe.
   107       if (mSupportsComponentAlphaChildren) {
   108         bool is2d = transform3D.Is2D(&transform);
   109         NS_ASSERTION(is2d, "Transform should be 2d when mSupportsComponentAlphaChildren.");
   111         // Copy background up from below. This applies any 2D transform that is
   112         // applied to use relative to our parent, and compensates for the offset
   113         // that was applied on our parent's rendering.
   114         D3D10_BOX srcBox;
   115         srcBox.left = std::max<int32_t>(visibleRect.x + int32_t(transform._31) - int32_t(previousRenderTargetOffset[0]), 0);
   116         srcBox.top = std::max<int32_t>(visibleRect.y + int32_t(transform._32) - int32_t(previousRenderTargetOffset[1]), 0);
   117         srcBox.right = std::min<int32_t>(srcBox.left + visibleRect.width, previousViewportSize.width);
   118         srcBox.bottom = std::min<int32_t>(srcBox.top + visibleRect.height, previousViewportSize.height);
   119         srcBox.back = 1;
   120         srcBox.front = 0;
   122         nsRefPtr<ID3D10Resource> srcResource;
   123         previousRTView->GetResource(getter_AddRefs(srcResource));
   125         device()->CopySubresourceRegion(renderTexture, 0,
   126                                         0, 0, 0,
   127                                         srcResource, 0,
   128                                         &srcBox);
   129       } else {
   130         float black[] = { 0, 0, 0, 0};
   131         device()->ClearRenderTargetView(rtView, black);
   132       }
   133     }
   135     ID3D10RenderTargetView *rtViewPtr = rtView;
   136     device()->OMSetRenderTargets(1, &rtViewPtr, nullptr);
   138     renderTargetOffset[0] = (float)visibleRect.x;
   139     renderTargetOffset[1] = (float)visibleRect.y;
   140     effect()->GetVariableByName("vRenderTargetOffset")->
   141       SetRawValue(renderTargetOffset, 0, 8);
   143     mD3DManager->SetViewport(nsIntSize(visibleRect.Size()));
   144   }
   146   D3D10_RECT oldD3D10Scissor;
   147   UINT numRects = 1;
   148   device()->RSGetScissorRects(&numRects, &oldD3D10Scissor);
   149   // Convert scissor to an nsIntRect. D3D10_RECT's are exclusive
   150   // on the bottom and right values.
   151   nsIntRect oldScissor(oldD3D10Scissor.left,
   152                        oldD3D10Scissor.top,
   153                        oldD3D10Scissor.right - oldD3D10Scissor.left,
   154                        oldD3D10Scissor.bottom - oldD3D10Scissor.top);
   156   nsAutoTArray<Layer*, 12> children;
   157   SortChildrenBy3DZOrder(children);
   159   /*
   160    * Render this container's contents.
   161    */
   162   for (uint32_t i = 0; i < children.Length(); i++) {
   163     LayerD3D10* layerToRender = static_cast<LayerD3D10*>(children.ElementAt(i)->ImplData());
   165     if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
   166       continue;
   167     }
   169     nsIntRect scissorRect =
   170         layerToRender->GetLayer()->CalculateScissorRect(oldScissor, nullptr);
   171     if (scissorRect.IsEmpty()) {
   172       continue;
   173     }
   175     D3D10_RECT d3drect;
   176     d3drect.left = scissorRect.x;
   177     d3drect.top = scissorRect.y;
   178     d3drect.right = scissorRect.x + scissorRect.width;
   179     d3drect.bottom = scissorRect.y + scissorRect.height;
   180     device()->RSSetScissorRects(1, &d3drect);
   182     layerToRender->RenderLayer();
   183   }
   185   device()->RSSetScissorRects(1, &oldD3D10Scissor);
   187   if (useIntermediate) {
   188     mD3DManager->SetViewport(previousViewportSize);
   189     ID3D10RenderTargetView *rtView = previousRTView;
   190     device()->OMSetRenderTargets(1, &rtView, nullptr);
   191     effect()->GetVariableByName("vRenderTargetOffset")->
   192       SetRawValue(previousRenderTargetOffset, 0, 8);
   194     SetEffectTransformAndOpacity();
   196     ID3D10EffectTechnique *technique;
   197     if (LoadMaskTexture()) {
   198       if (GetTransform().CanDraw2D()) {
   199         technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_MASK);
   200       } else {
   201         technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_MASK_3D);
   202       }
   203     } else {
   204         technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_NO_MASK);
   205     }
   207     effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
   208       ShaderConstantRectD3D10(
   209         (float)visibleRect.x,
   210         (float)visibleRect.y,
   211         (float)visibleRect.width,
   212         (float)visibleRect.height)
   213       );
   215     technique->GetPassByIndex(0)->Apply(0);
   217     ID3D10ShaderResourceView *view;
   218     device()->CreateShaderResourceView(renderTexture, nullptr, &view);
   219     device()->PSSetShaderResources(0, 1, &view);    
   220     device()->Draw(4, 0);
   221     view->Release();
   222   }
   223 }
   225 void
   226 ContainerLayerD3D10::LayerManagerDestroyed()
   227 {
   228   while (mFirstChild) {
   229     GetFirstChildD3D10()->LayerManagerDestroyed();
   230     RemoveChild(mFirstChild);
   231   }
   232 }
   234 void
   235 ContainerLayerD3D10::Validate()
   236 {
   237   nsIntRect visibleRect = mVisibleRegion.GetBounds();
   239   mSupportsComponentAlphaChildren = false;
   241   if (UseIntermediateSurface()) {
   242     Matrix4x4 transform3D = GetEffectiveTransform();
   243     Matrix transform;
   245     if (mVisibleRegion.GetNumRects() == 1 && (GetContentFlags() & CONTENT_OPAQUE)) {
   246       // don't need a background, we're going to paint all opaque stuff
   247       mSupportsComponentAlphaChildren = true;
   248     } else {
   249       if (HasOpaqueAncestorLayer(this) &&
   250           transform3D.Is2D(&transform) && !ThebesMatrix(transform).HasNonIntegerTranslation() &&
   251           GetParent()->GetEffectiveVisibleRegion().GetBounds().Contains(visibleRect))
   252       {
   253         // In this case we can copy up the background. See RenderLayer.
   254         mSupportsComponentAlphaChildren = true;
   255       }
   256     }
   257   } else {
   258     mSupportsComponentAlphaChildren = (GetContentFlags() & CONTENT_OPAQUE) ||
   259         (mParent && mParent->SupportsComponentAlphaChildren());
   260   }
   262   ReadbackProcessor readback;
   263   readback.BuildUpdates(this);
   265   Layer *layer = GetFirstChild();
   266   while (layer) {
   267     if (layer->GetType() == TYPE_THEBES) {
   268       static_cast<ThebesLayerD3D10*>(layer)->Validate(&readback);
   269     } else {
   270       static_cast<LayerD3D10*>(layer->ImplData())->Validate();
   271     }
   272     layer = layer->GetNextSibling();
   273   }
   274 }
   276 } /* layers */
   277 } /* mozilla */

mercurial