gfx/layers/d3d9/ContainerLayerD3D9.cpp

changeset 0
6474c204b198
     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 */

mercurial