summaryrefslogtreecommitdiffstats
path: root/gfx/2d/FilterNodeD2D1.h
blob: a2f6e684f9e1054b18ddc4722486cdb31f2a914c (plain)
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* -*- 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/. */

#ifndef MOZILLA_GFX_FILTERNODED2D1_H_
#define MOZILLA_GFX_FILTERNODED2D1_H_

#include "2D.h"
#include "Filters.h"
#include <vector>
#include <windows.h>
#include <d2d1_1.h>
#include <cguid.h>

namespace mozilla {
namespace gfx {

class FilterNodeD2D1 : public FilterNode {
 public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeD2D1, override)

  static already_AddRefed<FilterNode> Create(ID2D1DeviceContext* aDC,
                                             FilterType aType);

  FilterNodeD2D1(ID2D1Effect* aEffect, FilterType aType)
      : mEffect(aEffect), mType(aType) {
    InitUnmappedProperties();
  }

  virtual FilterBackend GetBackendType() { return FILTER_BACKEND_DIRECT2D1_1; }

  virtual void SetInput(uint32_t aIndex, SourceSurface* aSurface);
  virtual void SetInput(uint32_t aIndex, FilterNode* aFilter);

  virtual void SetAttribute(uint32_t aIndex, uint32_t aValue);
  virtual void SetAttribute(uint32_t aIndex, Float aValue);
  virtual void SetAttribute(uint32_t aIndex, const Point& aValue);
  virtual void SetAttribute(uint32_t aIndex, const Matrix5x4& aValue);
  virtual void SetAttribute(uint32_t aIndex, const Point3D& aValue);
  virtual void SetAttribute(uint32_t aIndex, const Size& aValue);
  virtual void SetAttribute(uint32_t aIndex, const IntSize& aValue);
  virtual void SetAttribute(uint32_t aIndex, const DeviceColor& aValue);
  virtual void SetAttribute(uint32_t aIndex, const Rect& aValue);
  virtual void SetAttribute(uint32_t aIndex, const IntRect& aValue);
  virtual void SetAttribute(uint32_t aIndex, bool aValue);
  virtual void SetAttribute(uint32_t aIndex, const Float* aValues,
                            uint32_t aSize);
  virtual void SetAttribute(uint32_t aIndex, const IntPoint& aValue);
  virtual void SetAttribute(uint32_t aIndex, const Matrix& aValue);

  // Called by DrawTarget before it draws our OutputEffect, and recursively
  // by the filter nodes that have this filter as one of their inputs. This
  // gives us a chance to convert any input surfaces to the target format for
  // the DrawTarget that we will draw to.
  virtual void WillDraw(DrawTarget* aDT);

  virtual ID2D1Effect* MainEffect() { return mEffect.get(); }
  virtual ID2D1Effect* InputEffect() { return mEffect.get(); }
  virtual ID2D1Effect* OutputEffect() { return mEffect.get(); }

 protected:
  friend class DrawTargetD2D1;
  friend class DrawTargetD2D;
  friend class FilterNodeConvolveD2D1;

  void InitUnmappedProperties();

  RefPtr<ID2D1Effect> mEffect;
  std::vector<RefPtr<FilterNodeD2D1>> mInputFilters;
  std::vector<RefPtr<SourceSurface>> mInputSurfaces;
  FilterType mType;

 private:
  using FilterNode::SetAttribute;
  using FilterNode::SetInput;
};

class FilterNodeConvolveD2D1 : public FilterNodeD2D1 {
 public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeConvolveD2D1, override)
  explicit FilterNodeConvolveD2D1(ID2D1DeviceContext* aDC);

  void SetInput(uint32_t aIndex, FilterNode* aFilter) override;

  void SetAttribute(uint32_t aIndex, uint32_t aValue) override;
  void SetAttribute(uint32_t aIndex, const IntSize& aValue) override;
  void SetAttribute(uint32_t aIndex, const IntPoint& aValue) override;
  void SetAttribute(uint32_t aIndex, const IntRect& aValue) override;

  ID2D1Effect* InputEffect() override;

 private:
  using FilterNode::SetAttribute;
  using FilterNode::SetInput;

  void UpdateChain();
  void UpdateOffset();
  void UpdateSourceRect();

  RefPtr<ID2D1Effect> mExtendInputEffect;
  RefPtr<ID2D1Effect> mBorderEffect;
  ConvolveMatrixEdgeMode mEdgeMode;
  IntPoint mTarget;
  IntSize mKernelSize;
  IntRect mSourceRect;
};

class FilterNodeOpacityD2D1 : public FilterNodeD2D1 {
 public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeOpacityD2D1, override)
  FilterNodeOpacityD2D1(ID2D1Effect* aEffect, FilterType aType)
      : FilterNodeD2D1(aEffect, aType) {}

  void SetAttribute(uint32_t aIndex, Float aValue) override;
};

class FilterNodeExtendInputAdapterD2D1 : public FilterNodeD2D1 {
 public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeExtendInputAdapterD2D1,
                                          override)
  FilterNodeExtendInputAdapterD2D1(ID2D1DeviceContext* aDC,
                                   FilterNodeD2D1* aFilterNode,
                                   FilterType aType);

  ID2D1Effect* InputEffect() override { return mExtendInputEffect.get(); }
  ID2D1Effect* OutputEffect() override {
    return mWrappedFilterNode->OutputEffect();
  }

 private:
  RefPtr<FilterNodeD2D1> mWrappedFilterNode;
  RefPtr<ID2D1Effect> mExtendInputEffect;
};

class FilterNodePremultiplyAdapterD2D1 : public FilterNodeD2D1 {
 public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodePremultiplyAdapterD2D1,
                                          override)
  FilterNodePremultiplyAdapterD2D1(ID2D1DeviceContext* aDC,
                                   FilterNodeD2D1* aFilterNode,
                                   FilterType aType);

  ID2D1Effect* InputEffect() override { return mPrePremultiplyEffect.get(); }
  ID2D1Effect* OutputEffect() override {
    return mPostUnpremultiplyEffect.get();
  }

 private:
  RefPtr<ID2D1Effect> mPrePremultiplyEffect;
  RefPtr<ID2D1Effect> mPostUnpremultiplyEffect;
};

}  // namespace gfx
}  // namespace mozilla

#endif