DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "FilterNodeCapture.h"

namespace mozilla {
namespace gfx {

struct Setter {
  Setter(FilterNode* aNode, DrawTarget* aDT, bool aInputsChanged)
      : mNode{aNode}, mIndex{0}, mDT{aDT}, mInputsChanged{aInputsChanged} {}
  template <typename T>
  void match(T& aValue) {
    mNode->SetAttribute(mIndex, aValue);
  }

  FilterNode* mNode;
  uint32_t mIndex;
  DrawTarget* mDT;
  bool mInputsChanged;
};

template <>
void Setter::match<std::vector<Float>>(std::vector<Float>& aValue) {
  mNode->SetAttribute(mIndex, aValue.data(), aValue.size());
}

template <>
void Setter::match<RefPtr<SourceSurface>>(RefPtr<SourceSurface>& aSurface) {
  if (!mInputsChanged) {
    return;
  }
  mNode->SetInput(mIndex, aSurface);
}

template <>
void Setter::match<RefPtr<FilterNode>>(RefPtr<FilterNode>& aNode) {
  RefPtr<FilterNode> node = aNode;
  if (node->GetBackendType() == FilterBackend::FILTER_BACKEND_CAPTURE) {
    FilterNodeCapture* captureNode =
        static_cast<FilterNodeCapture*>(node.get());
    node = captureNode->Validate(mDT);
  }
  if (!mInputsChanged) {
    return;
  }

  mNode->SetInput(mIndex, node);
}

RefPtr<FilterNode> FilterNodeCapture::Validate(DrawTarget* aDT) {
  if (!mFilterNodeInternal) {
    mFilterNodeInternal = aDT->CreateFilter(mType);
  }

  if (!mFilterNodeInternal) {
    return nullptr;
  }

  Setter setter(mFilterNodeInternal, aDT, mInputsChanged);

  for (auto attribute : mAttributes) {
    setter.mIndex = attribute.first;
    // Variant's matching doesn't seem to compile to terribly efficient code,
    // this is probably fine since this happens on the paint thread, if ever
    // needed it would be fairly simple to write something more optimized.
    attribute.second.match(setter);
  }
  mAttributes.clear();

  for (auto input : mInputs) {
    setter.mIndex = input.first;
    input.second.match(setter);
  }
  mInputsChanged = false;

  return mFilterNodeInternal.get();
}

void FilterNodeCapture::SetAttribute(uint32_t aIndex, const Float* aValues,
                                     uint32_t aSize) {
  std::vector<Float> vec(aSize);
  memcpy(vec.data(), aValues, sizeof(Float) * aSize);
  AttributeValue att(std::move(vec));
  auto result = mAttributes.insert({aIndex, att});
  if (!result.second) {
    result.first->second = att;
  }
}

}  // namespace gfx
}  // namespace mozilla