1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef _MOZILLA_GFX_DRAWTARGETSKIA_H
8 #define _MOZILLA_GFX_DRAWTARGETSKIA_H
9 
10 #include "2D.h"
11 #include <sstream>
12 #include <vector>
13 
14 #ifdef MOZ_WIDGET_COCOA
15 #  include <ApplicationServices/ApplicationServices.h>
16 #endif
17 
18 class SkCanvas;
19 class SkSurface;
20 
21 namespace mozilla {
22 
23 template <>
24 class RefPtrTraits<SkSurface> {
25  public:
26   static void Release(SkSurface* aSurface);
27   static void AddRef(SkSurface* aSurface);
28 };
29 
30 namespace gfx {
31 
32 class DataSourceSurface;
33 class SourceSurfaceSkia;
34 class BorrowedCGContext;
35 
36 class DrawTargetSkia : public DrawTarget {
37  public:
38   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetSkia, override)
39   DrawTargetSkia();
40   virtual ~DrawTargetSkia();
41 
42   virtual DrawTargetType GetType() const override;
GetBackendType()43   virtual BackendType GetBackendType() const override {
44     return BackendType::SKIA;
45   }
46   already_AddRefed<SourceSurface> Snapshot(SurfaceFormat aFormat);
Snapshot()47   virtual already_AddRefed<SourceSurface> Snapshot() override {
48     return Snapshot(mFormat);
49   }
50   already_AddRefed<SourceSurface> GetBackingSurface() override;
GetSize()51   virtual IntSize GetSize() const override { return mSize; };
52   virtual bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride,
53                         SurfaceFormat* aFormat,
54                         IntPoint* aOrigin = nullptr) override;
55   virtual void ReleaseBits(uint8_t* aData) override;
56   virtual void Flush() override;
57   virtual void DrawSurface(
58       SourceSurface* aSurface, const Rect& aDest, const Rect& aSource,
59       const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
60       const DrawOptions& aOptions = DrawOptions()) override;
61   virtual void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
62                           const Point& aDestPoint,
63                           const DrawOptions& aOptions = DrawOptions()) override;
64   virtual void DrawSurfaceWithShadow(SourceSurface* aSurface,
65                                      const Point& aDest,
66                                      const DeviceColor& aColor,
67                                      const Point& aOffset, Float aSigma,
68                                      CompositionOp aOperator) override;
69   void Clear(const Rect* aRect = nullptr);
ClearRect(const Rect & aRect)70   virtual void ClearRect(const Rect& aRect) override { Clear(&aRect); }
71   void BlendSurface(SourceSurface* aSurface, const IntRect& aSourceRect,
72                     const IntPoint& aDestination, CompositionOp aOperator);
CopySurface(SourceSurface * aSurface,const IntRect & aSourceRect,const IntPoint & aDestination)73   virtual void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
74                            const IntPoint& aDestination) override {
75     BlendSurface(aSurface, aSourceRect, aDestination, CompositionOp::OP_SOURCE);
76   }
77   virtual void FillRect(const Rect& aRect, const Pattern& aPattern,
78                         const DrawOptions& aOptions = DrawOptions()) override;
79   virtual void StrokeRect(const Rect& aRect, const Pattern& aPattern,
80                           const StrokeOptions& aStrokeOptions = StrokeOptions(),
81                           const DrawOptions& aOptions = DrawOptions()) override;
82   virtual void StrokeLine(const Point& aStart, const Point& aEnd,
83                           const Pattern& aPattern,
84                           const StrokeOptions& aStrokeOptions = StrokeOptions(),
85                           const DrawOptions& aOptions = DrawOptions()) override;
86   virtual void Stroke(const Path* aPath, const Pattern& aPattern,
87                       const StrokeOptions& aStrokeOptions = StrokeOptions(),
88                       const DrawOptions& aOptions = DrawOptions()) override;
89   virtual void Fill(const Path* aPath, const Pattern& aPattern,
90                     const DrawOptions& aOptions = DrawOptions()) override;
91 
92   virtual void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
93                           const Pattern& aPattern,
94                           const DrawOptions& aOptions = DrawOptions()) override;
95   virtual void StrokeGlyphs(
96       ScaledFont* aFont, const GlyphBuffer& aBuffer, const Pattern& aPattern,
97       const StrokeOptions& aStrokeOptions = StrokeOptions(),
98       const DrawOptions& aOptions = DrawOptions()) override;
99   virtual void Mask(const Pattern& aSource, const Pattern& aMask,
100                     const DrawOptions& aOptions = DrawOptions()) override;
101   virtual void MaskSurface(
102       const Pattern& aSource, SourceSurface* aMask, Point aOffset,
103       const DrawOptions& aOptions = DrawOptions()) override;
104   virtual bool Draw3DTransformedSurface(SourceSurface* aSurface,
105                                         const Matrix4x4& aMatrix) override;
106   virtual void PushClip(const Path* aPath) override;
107   virtual void PushClipRect(const Rect& aRect) override;
108   virtual void PushDeviceSpaceClipRects(const IntRect* aRects,
109                                         uint32_t aCount) override;
110   virtual void PopClip() override;
111   virtual void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
112                          const Matrix& aMaskTransform,
113                          const IntRect& aBounds = IntRect(),
114                          bool aCopyBackground = false) override;
115   virtual void PushLayerWithBlend(
116       bool aOpaque, Float aOpacity, SourceSurface* aMask,
117       const Matrix& aMaskTransform, const IntRect& aBounds = IntRect(),
118       bool aCopyBackground = false,
119       CompositionOp aCompositionOp = CompositionOp::OP_OVER) override;
120   virtual void PopLayer() override;
121   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
122       unsigned char* aData, const IntSize& aSize, int32_t aStride,
123       SurfaceFormat aFormat) const override;
124   virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(
125       SourceSurface* aSurface) const override;
126   virtual already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(
127       SourceSurface* aSurface) const override;
128   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
129       const NativeSurface& aSurface) const override;
130   virtual already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
131       const IntSize& aSize, SurfaceFormat aFormat) const override;
132   virtual bool CanCreateSimilarDrawTarget(const IntSize& aSize,
133                                           SurfaceFormat aFormat) const override;
134   virtual RefPtr<DrawTarget> CreateClippedDrawTarget(
135       const Rect& aBounds, SurfaceFormat aFormat) override;
136 
137   virtual already_AddRefed<PathBuilder> CreatePathBuilder(
138       FillRule aFillRule = FillRule::FILL_WINDING) const override;
139   virtual already_AddRefed<GradientStops> CreateGradientStops(
140       GradientStop* aStops, uint32_t aNumStops,
141       ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
142   virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
143   virtual void SetTransform(const Matrix& aTransform) override;
144   virtual void* GetNativeSurface(NativeSurfaceType aType) override;
DetachAllSnapshots()145   virtual void DetachAllSnapshots() override { MarkChanged(); }
146 
147   bool Init(const IntSize& aSize, SurfaceFormat aFormat);
148   bool Init(unsigned char* aData, const IntSize& aSize, int32_t aStride,
149             SurfaceFormat aFormat, bool aUninitialized = false);
150   bool Init(SkCanvas* aCanvas);
151   bool Init(RefPtr<DataSourceSurface>&& aSurface);
152 
153   // Skia assumes that texture sizes fit in 16-bit signed integers.
GetMaxSurfaceSize()154   static size_t GetMaxSurfaceSize() { return 32767; }
155 
string()156   operator std::string() const {
157     std::stringstream stream;
158     stream << "DrawTargetSkia(" << this << ")";
159     return stream.str();
160   }
161 
162   Maybe<Rect> GetDeviceClipRect() const;
163 
164   Maybe<Rect> GetGlyphLocalBounds(ScaledFont* aFont, const GlyphBuffer& aBuffer,
165                                   const Pattern& aPattern,
166                                   const StrokeOptions* aStrokeOptions,
167                                   const DrawOptions& aOptions);
168 
169  private:
170   friend class SourceSurfaceSkia;
171 
172   static void ReleaseMappedSkSurface(void* aPixels, void* aContext);
173 
174   void MarkChanged();
175 
176   void DrawGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
177                   const Pattern& aPattern,
178                   const StrokeOptions* aStrokeOptions = nullptr,
179                   const DrawOptions& aOptions = DrawOptions());
180 
181   struct PushedLayer {
PushedLayerPushedLayer182     PushedLayer(bool aOldPermitSubpixelAA, SourceSurface* aMask)
183         : mOldPermitSubpixelAA(aOldPermitSubpixelAA), mMask(aMask) {}
184     bool mOldPermitSubpixelAA;
185     RefPtr<SourceSurface> mMask;
186   };
187   std::vector<PushedLayer> mPushedLayers;
188 
189   IntSize mSize;
190   RefPtr<SkSurface> mSurface;
191   SkCanvas* mCanvas = nullptr;
192   RefPtr<DataSourceSurface> mBackingSurface;
193   RefPtr<SourceSurfaceSkia> mSnapshot;
194   Mutex mSnapshotLock;
195 
196 #ifdef MOZ_WIDGET_COCOA
197   friend class BorrowedCGContext;
198 
199   CGContextRef BorrowCGContext(const DrawOptions& aOptions);
200   void ReturnCGContext(CGContextRef);
201   bool FillGlyphsWithCG(ScaledFont* aFont, const GlyphBuffer& aBuffer,
202                         const Pattern& aPattern,
203                         const DrawOptions& aOptions = DrawOptions());
204 
205   CGContextRef mCG;
206   CGColorSpaceRef mColorSpace;
207   uint8_t* mCanvasData;
208   IntSize mCGSize;
209   bool mNeedLayer;
210 #endif
211 };
212 
213 }  // namespace gfx
214 }  // namespace mozilla
215 
216 #endif  // _MOZILLA_GFX_SOURCESURFACESKIA_H
217