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_DRAWTARGETTILED_H_ 8 #define MOZILLA_GFX_DRAWTARGETTILED_H_ 9 10 #include "2D.h" 11 12 #include "mozilla/Vector.h" 13 14 #include "Filters.h" 15 #include "Logging.h" 16 17 #include <vector> 18 19 namespace mozilla { 20 namespace gfx { 21 22 struct TileInternal : public Tile { TileInternalTileInternal23 TileInternal() : mClippedOut(false) {} 24 TileInternalTileInternal25 explicit TileInternal(const Tile& aOther) 26 : Tile(aOther), mClippedOut(false) {} 27 28 bool mClippedOut; 29 }; 30 31 class DrawTargetTiled : public DrawTarget { 32 public: 33 DrawTargetTiled(); 34 35 bool Init(const TileSet& mTiles); 36 IsTiledDrawTarget()37 bool IsTiledDrawTarget() const override { return true; } 38 IsCaptureDT()39 bool IsCaptureDT() const override { 40 return mTiles[0].mDrawTarget->IsCaptureDT(); 41 } GetType()42 DrawTargetType GetType() const override { 43 return mTiles[0].mDrawTarget->GetType(); 44 } GetBackendType()45 BackendType GetBackendType() const override { 46 return mTiles[0].mDrawTarget->GetBackendType(); 47 } 48 already_AddRefed<SourceSurface> Snapshot() override; 49 void DetachAllSnapshots() override; GetSize()50 IntSize GetSize() const override { 51 MOZ_ASSERT(mRect.Width() > 0 && mRect.Height() > 0); 52 return IntSize(mRect.XMost(), mRect.YMost()); 53 } GetRect()54 IntRect GetRect() const override { return mRect; } 55 56 void Flush() override; 57 void DrawSurface(SourceSurface* aSurface, const Rect& aDest, 58 const Rect& aSource, const DrawSurfaceOptions& aSurfOptions, 59 const DrawOptions& aOptions) override; 60 void DrawFilter(FilterNode* aNode, const Rect& aSourceRect, 61 const Point& aDestPoint, 62 const DrawOptions& aOptions = DrawOptions()) override; DrawSurfaceWithShadow(SourceSurface * aSurface,const Point & aDest,const DeviceColor & aColor,const Point & aOffset,Float aSigma,CompositionOp aOperator)63 void DrawSurfaceWithShadow( 64 SourceSurface* aSurface, const Point& aDest, const DeviceColor& aColor, 65 const Point& aOffset, Float aSigma, 66 CompositionOp aOperator) override { /* Not implemented */ 67 MOZ_CRASH("GFX: DrawSurfaceWithShadow"); 68 } 69 70 void ClearRect(const Rect& aRect) override; 71 void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset, 72 const DrawOptions& aOptions = DrawOptions()) override; 73 74 void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect, 75 const IntPoint& aDestination) override; 76 77 void FillRect(const Rect& aRect, const Pattern& aPattern, 78 const DrawOptions& aOptions = DrawOptions()) override; 79 void StrokeRect(const Rect& aRect, const Pattern& aPattern, 80 const StrokeOptions& aStrokeOptions = StrokeOptions(), 81 const DrawOptions& aOptions = DrawOptions()) override; 82 void StrokeLine(const Point& aStart, const Point& aEnd, 83 const Pattern& aPattern, 84 const StrokeOptions& aStrokeOptions = StrokeOptions(), 85 const DrawOptions& aOptions = DrawOptions()) override; 86 void Stroke(const Path* aPath, const Pattern& aPattern, 87 const StrokeOptions& aStrokeOptions = StrokeOptions(), 88 const DrawOptions& aOptions = DrawOptions()) override; 89 void Fill(const Path* aPath, const Pattern& aPattern, 90 const DrawOptions& aOptions = DrawOptions()) override; 91 void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, 92 const Pattern& aPattern, 93 const DrawOptions& aOptions = DrawOptions()) override; 94 void Mask(const Pattern& aSource, const Pattern& aMask, 95 const DrawOptions& aOptions = DrawOptions()) override; 96 void PushClip(const Path* aPath) override; 97 void PushClipRect(const Rect& aRect) override; 98 void PopClip() override; 99 void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask, 100 const Matrix& aMaskTransform, 101 const IntRect& aBounds = IntRect(), 102 bool aCopyBackground = false) override; 103 void PushLayerWithBlend(bool aOpaque, Float aOpacity, SourceSurface* aMask, 104 const Matrix& aMaskTransform, 105 const IntRect& aBounds = IntRect(), 106 bool aCopyBackground = false, 107 CompositionOp = CompositionOp::OP_OVER) override; 108 void PopLayer() override; 109 110 void PadEdges(const IntRegion& aRegion) override; 111 112 void SetTransform(const Matrix& aTransform) override; 113 114 void SetPermitSubpixelAA(bool aPermitSubpixelAA) override; 115 CreateSourceSurfaceFromData(unsigned char * aData,const IntSize & aSize,int32_t aStride,SurfaceFormat aFormat)116 already_AddRefed<SourceSurface> CreateSourceSurfaceFromData( 117 unsigned char* aData, const IntSize& aSize, int32_t aStride, 118 SurfaceFormat aFormat) const override { 119 return mTiles[0].mDrawTarget->CreateSourceSurfaceFromData(aData, aSize, 120 aStride, aFormat); 121 } OptimizeSourceSurface(SourceSurface * aSurface)122 already_AddRefed<SourceSurface> OptimizeSourceSurface( 123 SourceSurface* aSurface) const override { 124 return mTiles[0].mDrawTarget->OptimizeSourceSurface(aSurface); 125 } 126 CreateSourceSurfaceFromNativeSurface(const NativeSurface & aSurface)127 already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface( 128 const NativeSurface& aSurface) const override { 129 return mTiles[0].mDrawTarget->CreateSourceSurfaceFromNativeSurface( 130 aSurface); 131 } 132 CreateSimilarDrawTarget(const IntSize & aSize,SurfaceFormat aFormat)133 already_AddRefed<DrawTarget> CreateSimilarDrawTarget( 134 const IntSize& aSize, SurfaceFormat aFormat) const override { 135 return mTiles[0].mDrawTarget->CreateSimilarDrawTarget(aSize, aFormat); 136 } 137 CanCreateSimilarDrawTarget(const IntSize & aSize,SurfaceFormat aFormat)138 bool CanCreateSimilarDrawTarget(const IntSize& aSize, 139 SurfaceFormat aFormat) const override { 140 return mTiles[0].mDrawTarget->CanCreateSimilarDrawTarget(aSize, aFormat); 141 } 142 143 RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds, 144 SurfaceFormat aFormat) override; 145 146 already_AddRefed<PathBuilder> CreatePathBuilder( 147 FillRule aFillRule = FillRule::FILL_WINDING) const override { 148 return mTiles[0].mDrawTarget->CreatePathBuilder(aFillRule); 149 } 150 151 already_AddRefed<GradientStops> CreateGradientStops( 152 GradientStop* aStops, uint32_t aNumStops, 153 ExtendMode aExtendMode = ExtendMode::CLAMP) const override { 154 return mTiles[0].mDrawTarget->CreateGradientStops(aStops, aNumStops, 155 aExtendMode); 156 } CreateFilter(FilterType aType)157 already_AddRefed<FilterNode> CreateFilter(FilterType aType) override { 158 return mTiles[0].mDrawTarget->CreateFilter(aType); 159 } 160 161 private: 162 std::vector<TileInternal> mTiles; 163 164 // mClippedOutTilesStack[clipIndex][tileIndex] is true if the tile at 165 // tileIndex has become completely clipped out at the clip stack depth 166 // clipIndex. 167 Vector<std::vector<bool>, 8> mClippedOutTilesStack; 168 169 IntRect mRect; 170 171 struct PushedLayer { PushedLayerPushedLayer172 explicit PushedLayer(bool aOldPermitSubpixelAA) 173 : mOldPermitSubpixelAA(aOldPermitSubpixelAA) {} 174 bool mOldPermitSubpixelAA; 175 }; 176 std::vector<PushedLayer> mPushedLayers; 177 }; 178 179 class SnapshotTiled : public SourceSurface { 180 public: SnapshotTiled(const std::vector<TileInternal> & aTiles,const IntRect & aRect)181 SnapshotTiled(const std::vector<TileInternal>& aTiles, const IntRect& aRect) 182 : mRect(aRect) { 183 for (size_t i = 0; i < aTiles.size(); i++) { 184 mSnapshots.push_back(aTiles[i].mDrawTarget->Snapshot()); 185 mOrigins.push_back(aTiles[i].mTileOrigin); 186 } 187 } 188 GetType()189 SurfaceType GetType() const override { return SurfaceType::TILED; } GetSize()190 IntSize GetSize() const override { 191 MOZ_ASSERT(mRect.Width() > 0 && mRect.Height() > 0); 192 return IntSize(mRect.XMost(), mRect.YMost()); 193 } GetRect()194 IntRect GetRect() const override { return mRect; } GetFormat()195 SurfaceFormat GetFormat() const override { 196 return mSnapshots[0]->GetFormat(); 197 } 198 GetDataSurface()199 already_AddRefed<DataSourceSurface> GetDataSurface() override { 200 RefPtr<DataSourceSurface> surf = 201 Factory::CreateDataSourceSurface(mRect.Size(), GetFormat()); 202 if (!surf) { 203 gfxCriticalError() 204 << "DrawTargetTiled::GetDataSurface failed to allocate surface"; 205 return nullptr; 206 } 207 208 DataSourceSurface::MappedSurface mappedSurf; 209 if (!surf->Map(DataSourceSurface::MapType::WRITE, &mappedSurf)) { 210 gfxCriticalError() 211 << "DrawTargetTiled::GetDataSurface failed to map surface"; 212 return nullptr; 213 } 214 215 { 216 RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForData( 217 BackendType::CAIRO, mappedSurf.mData, mRect.Size(), 218 mappedSurf.mStride, GetFormat()); 219 220 if (!dt) { 221 gfxWarning() << "DrawTargetTiled::GetDataSurface failed in " 222 "CreateDrawTargetForData"; 223 surf->Unmap(); 224 return nullptr; 225 } 226 for (size_t i = 0; i < mSnapshots.size(); i++) { 227 RefPtr<DataSourceSurface> dataSurf = mSnapshots[i]->GetDataSurface(); 228 dt->CopySurface(dataSurf, 229 IntRect(IntPoint(0, 0), mSnapshots[i]->GetSize()), 230 mOrigins[i] - mRect.TopLeft()); 231 } 232 } 233 surf->Unmap(); 234 235 return surf.forget(); 236 } 237 238 std::vector<RefPtr<SourceSurface>> mSnapshots; 239 std::vector<IntPoint> mOrigins; 240 IntRect mRect; 241 }; 242 243 } // namespace gfx 244 } // namespace mozilla 245 246 #endif 247