LCOV - code coverage report
Current view: top level - gfx/2d - DrawTargetWrapAndRecord.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 360 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 86 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; 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             : #include "DrawTargetWrapAndRecord.h"
       8             : #include "PathRecording.h"
       9             : #include <stdio.h>
      10             : 
      11             : #include "Logging.h"
      12             : #include "Tools.h"
      13             : #include "Filters.h"
      14             : #include "mozilla/UniquePtr.h"
      15             : #include "RecordingTypes.h"
      16             : #include "RecordedEventImpl.h"
      17             : 
      18             : namespace mozilla {
      19             : namespace gfx {
      20             : 
      21           0 : struct WrapAndRecordSourceSurfaceUserData
      22             : {
      23             :   void *refPtr;
      24             :   RefPtr<DrawEventRecorderPrivate> recorder;
      25             : };
      26             : 
      27           0 : void WrapAndRecordSourceSurfaceUserDataFunc(void *aUserData)
      28             : {
      29             :   WrapAndRecordSourceSurfaceUserData *userData =
      30           0 :     static_cast<WrapAndRecordSourceSurfaceUserData*>(aUserData);
      31             : 
      32           0 :   userData->recorder->RemoveSourceSurface((SourceSurface*)userData->refPtr);
      33           0 :   userData->recorder->RemoveStoredObject(userData->refPtr);
      34           0 :   userData->recorder->RecordEvent(
      35           0 :     RecordedSourceSurfaceDestruction(ReferencePtr(userData->refPtr)));
      36             : 
      37           0 :   delete userData;
      38           0 : }
      39             : 
      40             : static void
      41           0 : StoreSourceSurface(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
      42             :                    DataSourceSurface *aDataSurf, const char *reason)
      43             : {
      44           0 :   if (!aDataSurf) {
      45           0 :     gfxWarning() << "Recording failed to record SourceSurface for " << reason;
      46             :     // Insert a bogus source surface.
      47           0 :     int32_t stride = aSurface->GetSize().width * BytesPerPixel(aSurface->GetFormat());
      48           0 :     UniquePtr<uint8_t[]> sourceData(new uint8_t[stride * aSurface->GetSize().height]());
      49             :     aRecorder->RecordEvent(
      50           0 :       RecordedSourceSurfaceCreation(aSurface, sourceData.get(), stride,
      51           0 :                                     aSurface->GetSize(), aSurface->GetFormat()));
      52             :   } else {
      53           0 :     DataSourceSurface::ScopedMap map(aDataSurf, DataSourceSurface::READ);
      54             :     aRecorder->RecordEvent(
      55           0 :       RecordedSourceSurfaceCreation(aSurface, map.GetData(), map.GetStride(),
      56           0 :                                     aDataSurf->GetSize(), aDataSurf->GetFormat()));
      57             :   }
      58           0 : }
      59             : 
      60             : static void
      61           0 : EnsureSurfaceStored(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
      62             :                     const char *reason)
      63             : {
      64           0 :   if (aRecorder->HasStoredObject(aSurface)) {
      65           0 :     return;
      66             :   }
      67             : 
      68           0 :   RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface();
      69           0 :   StoreSourceSurface(aRecorder, aSurface, dataSurf, reason);
      70           0 :   aRecorder->AddStoredObject(aSurface);
      71           0 :   aRecorder->AddSourceSurface(aSurface);
      72             : 
      73           0 :   WrapAndRecordSourceSurfaceUserData *userData = new WrapAndRecordSourceSurfaceUserData;
      74           0 :   userData->refPtr = aSurface;
      75           0 :   userData->recorder = aRecorder;
      76             :   aSurface->AddUserData(reinterpret_cast<UserDataKey*>(aRecorder),
      77           0 :                         userData, &WrapAndRecordSourceSurfaceUserDataFunc);
      78           0 :   return;
      79             : }
      80             : 
      81             : class SourceSurfaceWrapAndRecord : public SourceSurface
      82             : {
      83             : public:
      84           0 :   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceWrapAndRecord)
      85           0 :   SourceSurfaceWrapAndRecord(SourceSurface *aFinalSurface, DrawEventRecorderPrivate *aRecorder)
      86           0 :     : mFinalSurface(aFinalSurface), mRecorder(aRecorder)
      87             :   {
      88           0 :     mRecorder->AddStoredObject(this);
      89           0 :   }
      90             : 
      91           0 :   ~SourceSurfaceWrapAndRecord()
      92           0 :   {
      93           0 :     mRecorder->RemoveStoredObject(this);
      94           0 :     mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(ReferencePtr(this)));
      95           0 :   }
      96             : 
      97           0 :   virtual SurfaceType GetType() const { return SurfaceType::RECORDING; }
      98           0 :   virtual IntSize GetSize() const { return mFinalSurface->GetSize(); }
      99           0 :   virtual SurfaceFormat GetFormat() const { return mFinalSurface->GetFormat(); }
     100           0 :   virtual already_AddRefed<DataSourceSurface> GetDataSurface() { return mFinalSurface->GetDataSurface(); }
     101             : 
     102             :   RefPtr<SourceSurface> mFinalSurface;
     103             :   RefPtr<DrawEventRecorderPrivate> mRecorder;
     104             : };
     105             : 
     106             : class GradientStopsWrapAndRecord : public GradientStops
     107             : {
     108             : public:
     109           0 :   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsWrapAndRecord)
     110           0 :   GradientStopsWrapAndRecord(GradientStops *aFinalGradientStops, DrawEventRecorderPrivate *aRecorder)
     111           0 :     : mFinalGradientStops(aFinalGradientStops), mRecorder(aRecorder)
     112             :   {
     113           0 :     mRecorder->AddStoredObject(this);
     114           0 :   }
     115             : 
     116           0 :   ~GradientStopsWrapAndRecord()
     117           0 :   {
     118           0 :     mRecorder->RemoveStoredObject(this);
     119           0 :     mRecorder->RecordEvent(RecordedGradientStopsDestruction(ReferencePtr(this)));
     120           0 :   }
     121             : 
     122           0 :   virtual BackendType GetBackendType() const { return BackendType::RECORDING; }
     123             : 
     124             :   RefPtr<GradientStops> mFinalGradientStops;
     125             :   RefPtr<DrawEventRecorderPrivate> mRecorder;
     126             : };
     127             : 
     128             : static SourceSurface *
     129           0 : GetSourceSurface(SourceSurface *aSurface)
     130             : {
     131           0 :   if (aSurface->GetType() != SurfaceType::RECORDING) {
     132           0 :     return aSurface;
     133             :   }
     134             : 
     135           0 :   return static_cast<SourceSurfaceWrapAndRecord*>(aSurface)->mFinalSurface;
     136             : }
     137             : 
     138             : static GradientStops *
     139           0 : GetGradientStops(GradientStops *aStops)
     140             : {
     141           0 :   if (aStops->GetBackendType() != BackendType::RECORDING) {
     142           0 :     return aStops;
     143             :   }
     144             : 
     145           0 :   return static_cast<GradientStopsWrapAndRecord*>(aStops)->mFinalGradientStops;
     146             : }
     147             : 
     148             : class FilterNodeWrapAndRecord : public FilterNode
     149             : {
     150             : public:
     151           0 :   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeWrapAndRecord, override)
     152             :   using FilterNode::SetAttribute;
     153             : 
     154           0 :   FilterNodeWrapAndRecord(FilterNode *aFinalFilterNode, DrawEventRecorderPrivate *aRecorder)
     155           0 :     : mFinalFilterNode(aFinalFilterNode), mRecorder(aRecorder)
     156             :   {
     157           0 :     mRecorder->AddStoredObject(this);
     158           0 :   }
     159             : 
     160           0 :   ~FilterNodeWrapAndRecord()
     161           0 :   {
     162           0 :     mRecorder->RemoveStoredObject(this);
     163           0 :     mRecorder->RecordEvent(RecordedFilterNodeDestruction(ReferencePtr(this)));
     164           0 :   }
     165             : 
     166             :   static FilterNode*
     167           0 :   GetFilterNode(FilterNode* aNode)
     168             :   {
     169           0 :     if (aNode->GetBackendType() != FILTER_BACKEND_RECORDING) {
     170           0 :       gfxWarning() << "Non recording filter node used with recording DrawTarget!";
     171           0 :       return aNode;
     172             :     }
     173             : 
     174           0 :     return static_cast<FilterNodeWrapAndRecord*>(aNode)->mFinalFilterNode;
     175             :   }
     176             : 
     177           0 :   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) override
     178             :   {
     179           0 :     EnsureSurfaceStored(mRecorder, aSurface,  "SetInput");
     180             : 
     181           0 :     mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface));
     182           0 :     mFinalFilterNode->SetInput(aIndex, GetSourceSurface(aSurface));
     183           0 :   }
     184           0 :   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) override
     185             :   {
     186           0 :     MOZ_ASSERT(mRecorder->HasStoredObject(aFilter));
     187             : 
     188           0 :     mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aFilter));
     189           0 :     mFinalFilterNode->SetInput(aIndex, GetFilterNode(aFilter));
     190           0 :   }
     191             : 
     192             : 
     193             : #define FORWARD_SET_ATTRIBUTE(type, argtype) \
     194             :   virtual void SetAttribute(uint32_t aIndex, type aValue) override { \
     195             :     mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aValue, RecordedFilterNodeSetAttribute::ARGTYPE_##argtype)); \
     196             :     mFinalFilterNode->SetAttribute(aIndex, aValue); \
     197             :   }
     198             : 
     199           0 :   FORWARD_SET_ATTRIBUTE(bool, BOOL);
     200           0 :   FORWARD_SET_ATTRIBUTE(uint32_t, UINT32);
     201           0 :   FORWARD_SET_ATTRIBUTE(Float, FLOAT);
     202           0 :   FORWARD_SET_ATTRIBUTE(const Size&, SIZE);
     203           0 :   FORWARD_SET_ATTRIBUTE(const IntSize&, INTSIZE);
     204           0 :   FORWARD_SET_ATTRIBUTE(const IntPoint&, INTPOINT);
     205           0 :   FORWARD_SET_ATTRIBUTE(const Rect&, RECT);
     206           0 :   FORWARD_SET_ATTRIBUTE(const IntRect&, INTRECT);
     207           0 :   FORWARD_SET_ATTRIBUTE(const Point&, POINT);
     208           0 :   FORWARD_SET_ATTRIBUTE(const Matrix&, MATRIX);
     209           0 :   FORWARD_SET_ATTRIBUTE(const Matrix5x4&, MATRIX5X4);
     210           0 :   FORWARD_SET_ATTRIBUTE(const Point3D&, POINT3D);
     211           0 :   FORWARD_SET_ATTRIBUTE(const Color&, COLOR);
     212             : 
     213             : #undef FORWARD_SET_ATTRIBUTE
     214             : 
     215           0 :   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) override {
     216           0 :     mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aFloat, aSize));
     217           0 :     mFinalFilterNode->SetAttribute(aIndex, aFloat, aSize);
     218           0 :   }
     219             : 
     220           0 :   virtual FilterBackend GetBackendType() override { return FILTER_BACKEND_RECORDING; }
     221             : 
     222             :   RefPtr<FilterNode> mFinalFilterNode;
     223             :   RefPtr<DrawEventRecorderPrivate> mRecorder;
     224             : };
     225             : 
     226             : struct AdjustedPattern
     227             : {
     228           0 :   explicit AdjustedPattern(const Pattern &aPattern)
     229           0 :     : mPattern(nullptr)
     230             :   {
     231           0 :     mOrigPattern = const_cast<Pattern*>(&aPattern);
     232           0 :   }
     233             : 
     234           0 :   ~AdjustedPattern() {
     235           0 :     if (mPattern) {
     236           0 :       mPattern->~Pattern();
     237             :     }
     238           0 :   }
     239             : 
     240           0 :   operator Pattern*()
     241             :   {
     242           0 :     switch(mOrigPattern->GetType()) {
     243             :     case PatternType::COLOR:
     244           0 :       return mOrigPattern;
     245             :     case PatternType::SURFACE:
     246             :       {
     247           0 :         SurfacePattern *surfPat = static_cast<SurfacePattern*>(mOrigPattern);
     248           0 :         mPattern =
     249           0 :           new (mSurfPat) SurfacePattern(GetSourceSurface(surfPat->mSurface),
     250             :                                         surfPat->mExtendMode, surfPat->mMatrix,
     251             :                                         surfPat->mSamplingFilter,
     252           0 :                                         surfPat->mSamplingRect);
     253           0 :         return mPattern;
     254             :       }
     255             :     case PatternType::LINEAR_GRADIENT:
     256             :       {
     257           0 :         LinearGradientPattern *linGradPat = static_cast<LinearGradientPattern*>(mOrigPattern);
     258           0 :         mPattern =
     259           0 :           new (mLinGradPat) LinearGradientPattern(linGradPat->mBegin, linGradPat->mEnd,
     260           0 :                                                   GetGradientStops(linGradPat->mStops),
     261           0 :                                                   linGradPat->mMatrix);
     262           0 :         return mPattern;
     263             :       }
     264             :     case PatternType::RADIAL_GRADIENT:
     265             :       {
     266           0 :         RadialGradientPattern *radGradPat = static_cast<RadialGradientPattern*>(mOrigPattern);
     267           0 :         mPattern =
     268           0 :           new (mRadGradPat) RadialGradientPattern(radGradPat->mCenter1, radGradPat->mCenter2,
     269             :                                                   radGradPat->mRadius1, radGradPat->mRadius2,
     270           0 :                                                   GetGradientStops(radGradPat->mStops),
     271           0 :                                                   radGradPat->mMatrix);
     272           0 :         return mPattern;
     273             :       }
     274             :     default:
     275           0 :       return new (mColPat) ColorPattern(Color());
     276             :     }
     277             : 
     278             :     return mPattern;
     279             :   }
     280             : 
     281             :   union {
     282             :     char mColPat[sizeof(ColorPattern)];
     283             :     char mLinGradPat[sizeof(LinearGradientPattern)];
     284             :     char mRadGradPat[sizeof(RadialGradientPattern)];
     285             :     char mSurfPat[sizeof(SurfacePattern)];
     286             :   };
     287             : 
     288             :   Pattern *mOrigPattern;
     289             :   Pattern *mPattern;
     290             : };
     291             : 
     292           0 : DrawTargetWrapAndRecord::DrawTargetWrapAndRecord(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData)
     293             :   : mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder))
     294           0 :   , mFinalDT(aDT)
     295             : {
     296           0 :   RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr;
     297           0 :   mRecorder->RecordEvent(RecordedDrawTargetCreation(this,
     298           0 :                                                     mFinalDT->GetBackendType(),
     299           0 :                                                     mFinalDT->GetSize(),
     300             :                                                     mFinalDT->GetFormat(),
     301           0 :                                                     aHasData, snapshot));
     302           0 :   mFormat = mFinalDT->GetFormat();
     303           0 : }
     304             : 
     305           0 : DrawTargetWrapAndRecord::DrawTargetWrapAndRecord(const DrawTargetWrapAndRecord *aDT,
     306           0 :                                          DrawTarget *aSimilarDT)
     307             :   : mRecorder(aDT->mRecorder)
     308           0 :   , mFinalDT(aSimilarDT)
     309             : {
     310           0 :   mRecorder->RecordEvent(RecordedCreateSimilarDrawTarget(this,
     311           0 :                                                          mFinalDT->GetSize(),
     312           0 :                                                          mFinalDT->GetFormat()));
     313           0 :   mFormat = mFinalDT->GetFormat();
     314           0 : }
     315             : 
     316           0 : DrawTargetWrapAndRecord::~DrawTargetWrapAndRecord()
     317             : {
     318           0 :   mRecorder->RecordEvent(RecordedDrawTargetDestruction(static_cast<DrawTarget*>(this)));
     319           0 : }
     320             : 
     321             : void
     322           0 : DrawTargetWrapAndRecord::FillRect(const Rect &aRect,
     323             :                               const Pattern &aPattern,
     324             :                               const DrawOptions &aOptions)
     325             : {
     326           0 :   EnsurePatternDependenciesStored(aPattern);
     327             : 
     328           0 :   mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions));
     329           0 :   mFinalDT->FillRect(aRect, *AdjustedPattern(aPattern), aOptions);
     330           0 : }
     331             : 
     332             : void
     333           0 : DrawTargetWrapAndRecord::StrokeRect(const Rect &aRect,
     334             :                                 const Pattern &aPattern,
     335             :                                 const StrokeOptions &aStrokeOptions,
     336             :                                 const DrawOptions &aOptions)
     337             : {
     338           0 :   EnsurePatternDependenciesStored(aPattern);
     339             : 
     340           0 :   mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions));
     341           0 :   mFinalDT->StrokeRect(aRect, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
     342           0 : }
     343             : 
     344             : void
     345           0 : DrawTargetWrapAndRecord::StrokeLine(const Point &aBegin,
     346             :                                 const Point &aEnd,
     347             :                                 const Pattern &aPattern,
     348             :                                 const StrokeOptions &aStrokeOptions,
     349             :                                 const DrawOptions &aOptions)
     350             : {
     351           0 :   EnsurePatternDependenciesStored(aPattern);
     352             : 
     353           0 :   mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions));
     354           0 :   mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
     355           0 : }
     356             : 
     357             : void
     358           0 : DrawTargetWrapAndRecord::Fill(const Path *aPath,
     359             :                           const Pattern &aPattern,
     360             :                           const DrawOptions &aOptions)
     361             : {
     362           0 :   RefPtr<PathRecording> pathWrapAndRecord = EnsurePathStored(aPath);
     363           0 :   EnsurePatternDependenciesStored(aPattern);
     364             : 
     365           0 :   mRecorder->RecordEvent(RecordedFill(this, pathWrapAndRecord, aPattern, aOptions));
     366           0 :   mFinalDT->Fill(pathWrapAndRecord->mPath, *AdjustedPattern(aPattern), aOptions);
     367           0 : }
     368             : 
     369           0 : struct WrapAndRecordFontUserData
     370             : {
     371             :   void *refPtr;
     372             :   RefPtr<DrawEventRecorderPrivate> recorder;
     373             : };
     374             : 
     375           0 : void WrapAndRecordFontUserDataDestroyFunc(void *aUserData)
     376             : {
     377             :   WrapAndRecordFontUserData *userData =
     378           0 :     static_cast<WrapAndRecordFontUserData*>(aUserData);
     379             : 
     380           0 :   userData->recorder->RecordEvent(RecordedScaledFontDestruction(ReferencePtr(userData->refPtr)));
     381           0 :   userData->recorder->RemoveScaledFont((ScaledFont*)userData->refPtr);
     382           0 :   delete userData;
     383           0 : }
     384             : 
     385             : void
     386           0 : DrawTargetWrapAndRecord::FillGlyphs(ScaledFont *aFont,
     387             :                                 const GlyphBuffer &aBuffer,
     388             :                                 const Pattern &aPattern,
     389             :                                 const DrawOptions &aOptions,
     390             :                                 const GlyphRenderingOptions *aRenderingOptions)
     391             : {
     392           0 :   EnsurePatternDependenciesStored(aPattern);
     393             : 
     394           0 :   UserDataKey* userDataKey = reinterpret_cast<UserDataKey*>(mRecorder.get());
     395           0 :   if (!aFont->GetUserData(userDataKey)) {
     396           0 :     UnscaledFont* unscaledFont = aFont->GetUnscaledFont();
     397           0 :     if (!mRecorder->HasStoredObject(unscaledFont)) {
     398           0 :       RecordedFontData fontData(unscaledFont);
     399             :       RecordedFontDetails fontDetails;
     400           0 :       if (fontData.GetFontDetails(fontDetails)) {
     401             :         // Try to serialise the whole font, just in case this is a web font that
     402             :         // is not present on the system.
     403           0 :         if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) {
     404           0 :           mRecorder->RecordEvent(fontData);
     405           0 :           mRecorder->AddStoredFontData(fontDetails.fontDataKey);
     406             :         }
     407           0 :         mRecorder->RecordEvent(RecordedUnscaledFontCreation(unscaledFont, fontDetails));
     408             :       } else {
     409             :         // If that fails, record just the font description and try to load it from
     410             :         // the system on the other side.
     411           0 :         RecordedFontDescriptor fontDesc(unscaledFont);
     412           0 :         if (fontDesc.IsValid()) {
     413           0 :           mRecorder->RecordEvent(fontDesc);
     414             :         } else {
     415           0 :           gfxWarning() << "DrawTargetWrapAndRecord::FillGlyphs failed to serialise UnscaledFont";
     416             :         }
     417             :       }
     418           0 :       mRecorder->AddStoredObject(unscaledFont);
     419             :     }
     420             : 
     421           0 :     mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, unscaledFont));
     422             : 
     423           0 :     WrapAndRecordFontUserData *userData = new WrapAndRecordFontUserData;
     424           0 :     userData->refPtr = aFont;
     425           0 :     userData->recorder = mRecorder;
     426           0 :     aFont->AddUserData(userDataKey, userData, &WrapAndRecordFontUserDataDestroyFunc);
     427           0 :     userData->recorder->AddScaledFont(aFont);
     428             :   }
     429             : 
     430           0 :   mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
     431           0 :   mFinalDT->FillGlyphs(aFont, aBuffer, *AdjustedPattern(aPattern), aOptions, aRenderingOptions);
     432           0 : }
     433             : 
     434             : void
     435           0 : DrawTargetWrapAndRecord::Mask(const Pattern &aSource,
     436             :                           const Pattern &aMask,
     437             :                           const DrawOptions &aOptions)
     438             : {
     439           0 :   EnsurePatternDependenciesStored(aSource);
     440           0 :   EnsurePatternDependenciesStored(aMask);
     441             : 
     442           0 :   mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions));
     443           0 :   mFinalDT->Mask(*AdjustedPattern(aSource), *AdjustedPattern(aMask), aOptions);
     444           0 : }
     445             : 
     446             : void
     447           0 : DrawTargetWrapAndRecord::MaskSurface(const Pattern &aSource,
     448             :                                  SourceSurface *aMask,
     449             :                                  Point aOffset,
     450             :                                  const DrawOptions &aOptions)
     451             : {
     452           0 :   EnsurePatternDependenciesStored(aSource);
     453           0 :   EnsureSurfaceStored(mRecorder, aMask, "MaskSurface");
     454             : 
     455           0 :   mRecorder->RecordEvent(RecordedMaskSurface(this, aSource, aMask, aOffset, aOptions));
     456           0 :   mFinalDT->MaskSurface(*AdjustedPattern(aSource), GetSourceSurface(aMask), aOffset, aOptions);
     457           0 : }
     458             : 
     459             : void
     460           0 : DrawTargetWrapAndRecord::Stroke(const Path *aPath,
     461             :                             const Pattern &aPattern,
     462             :                             const StrokeOptions &aStrokeOptions,
     463             :                             const DrawOptions &aOptions)
     464             : {
     465           0 :   RefPtr<PathRecording> pathWrapAndRecord = EnsurePathStored(aPath);
     466           0 :   EnsurePatternDependenciesStored(aPattern);
     467             : 
     468           0 :   mRecorder->RecordEvent(RecordedStroke(this, pathWrapAndRecord, aPattern, aStrokeOptions, aOptions));
     469           0 :   mFinalDT->Stroke(pathWrapAndRecord->mPath, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
     470           0 : }
     471             : 
     472             : already_AddRefed<SourceSurface>
     473           0 : DrawTargetWrapAndRecord::Snapshot()
     474             : {
     475           0 :   RefPtr<SourceSurface> surf = mFinalDT->Snapshot();
     476             : 
     477           0 :   RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
     478             : 
     479           0 :   mRecorder->RecordEvent(RecordedSnapshot(retSurf, this));
     480             : 
     481           0 :   return retSurf.forget();
     482             : }
     483             : 
     484             : already_AddRefed<SourceSurface>
     485           0 : DrawTargetWrapAndRecord::IntoLuminanceSource(LuminanceType aLuminanceType, float aOpacity)
     486             : {
     487           0 :   RefPtr<SourceSurface> surf = mFinalDT->IntoLuminanceSource(aLuminanceType, aOpacity);
     488             : 
     489           0 :   RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
     490             : 
     491           0 :   mRecorder->RecordEvent(RecordedIntoLuminanceSource(retSurf, this, aLuminanceType, aOpacity));
     492             : 
     493           0 :   return retSurf.forget();
     494             : }
     495             : 
     496             : void
     497           0 : DrawTargetWrapAndRecord::DetachAllSnapshots()
     498             : {
     499           0 :   mFinalDT->DetachAllSnapshots();
     500           0 : }
     501             : 
     502             : void
     503           0 : DrawTargetWrapAndRecord::DrawSurface(SourceSurface *aSurface,
     504             :                                  const Rect &aDest,
     505             :                                  const Rect &aSource,
     506             :                                  const DrawSurfaceOptions &aSurfOptions,
     507             :                                  const DrawOptions &aOptions)
     508             : {
     509           0 :   EnsureSurfaceStored(mRecorder, aSurface, "DrawSurface");
     510             : 
     511           0 :   mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions));
     512           0 :   mFinalDT->DrawSurface(GetSourceSurface(aSurface), aDest, aSource, aSurfOptions, aOptions);
     513           0 : }
     514             : 
     515             : void
     516           0 : DrawTargetWrapAndRecord::DrawSurfaceWithShadow(SourceSurface *aSurface,
     517             :                                            const Point &aDest,
     518             :                                            const Color &aColor,
     519             :                                            const Point &aOffset,
     520             :                                            Float aSigma,
     521             :                                            CompositionOp aOp)
     522             : {
     523           0 :   EnsureSurfaceStored(mRecorder, aSurface, "DrawSurfaceWithShadow");
     524             : 
     525           0 :   mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp));
     526           0 :   mFinalDT->DrawSurfaceWithShadow(GetSourceSurface(aSurface), aDest, aColor, aOffset, aSigma, aOp);
     527           0 : }
     528             : 
     529             : void
     530           0 : DrawTargetWrapAndRecord::DrawFilter(FilterNode *aNode,
     531             :                                 const Rect &aSourceRect,
     532             :                                 const Point &aDestPoint,
     533             :                                 const DrawOptions &aOptions)
     534             : {
     535           0 :   MOZ_ASSERT(mRecorder->HasStoredObject(aNode));
     536             : 
     537           0 :   mRecorder->RecordEvent(RecordedDrawFilter(this, aNode, aSourceRect, aDestPoint, aOptions));
     538           0 :   mFinalDT->DrawFilter(FilterNodeWrapAndRecord::GetFilterNode(aNode), aSourceRect, aDestPoint, aOptions);
     539           0 : }
     540             : 
     541             : already_AddRefed<FilterNode>
     542           0 : DrawTargetWrapAndRecord::CreateFilter(FilterType aType)
     543             : {
     544           0 :   RefPtr<FilterNode> node = mFinalDT->CreateFilter(aType);
     545             : 
     546           0 :   RefPtr<FilterNode> retNode = new FilterNodeWrapAndRecord(node, mRecorder);
     547             : 
     548           0 :   mRecorder->RecordEvent(RecordedFilterNodeCreation(retNode, aType));
     549             : 
     550           0 :   return retNode.forget();
     551             : }
     552             : 
     553             : void
     554           0 : DrawTargetWrapAndRecord::ClearRect(const Rect &aRect)
     555             : {
     556           0 :   mRecorder->RecordEvent(RecordedClearRect(this, aRect));
     557           0 :   mFinalDT->ClearRect(aRect);
     558           0 : }
     559             : 
     560             : void
     561           0 : DrawTargetWrapAndRecord::CopySurface(SourceSurface *aSurface,
     562             :                                  const IntRect &aSourceRect,
     563             :                                  const IntPoint &aDestination)
     564             : {
     565           0 :   EnsureSurfaceStored(mRecorder, aSurface, "CopySurface");
     566             : 
     567           0 :   mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination));
     568           0 :   mFinalDT->CopySurface(GetSourceSurface(aSurface), aSourceRect, aDestination);
     569           0 : }
     570             : 
     571             : void
     572           0 : DrawTargetWrapAndRecord::PushClip(const Path *aPath)
     573             : {
     574           0 :   RefPtr<PathRecording> pathWrapAndRecord = EnsurePathStored(aPath);
     575             : 
     576           0 :   mRecorder->RecordEvent(RecordedPushClip(this, pathWrapAndRecord));
     577           0 :   mFinalDT->PushClip(pathWrapAndRecord->mPath);
     578           0 : }
     579             : 
     580             : void
     581           0 : DrawTargetWrapAndRecord::PushClipRect(const Rect &aRect)
     582             : {
     583           0 :   mRecorder->RecordEvent(RecordedPushClipRect(this, aRect));
     584           0 :   mFinalDT->PushClipRect(aRect);
     585           0 : }
     586             : 
     587             : void
     588           0 : DrawTargetWrapAndRecord::PopClip()
     589             : {
     590           0 :   mRecorder->RecordEvent(RecordedPopClip(static_cast<DrawTarget*>(this)));
     591           0 :   mFinalDT->PopClip();
     592           0 : }
     593             : 
     594             : void
     595           0 : DrawTargetWrapAndRecord::PushLayer(bool aOpaque, Float aOpacity,
     596             :                                SourceSurface* aMask,
     597             :                                const Matrix& aMaskTransform,
     598             :                                const IntRect& aBounds, bool aCopyBackground)
     599             : {
     600           0 :   if (aMask) {
     601           0 :     EnsureSurfaceStored(mRecorder, aMask, "PushLayer");
     602             :   }
     603             : 
     604           0 :   mRecorder->RecordEvent(RecordedPushLayer(this, aOpaque, aOpacity, aMask,
     605             :                                            aMaskTransform, aBounds,
     606           0 :                                            aCopyBackground));
     607           0 :   mFinalDT->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, aBounds,
     608           0 :                       aCopyBackground);
     609           0 : }
     610             : 
     611             : void
     612           0 : DrawTargetWrapAndRecord::PopLayer()
     613             : {
     614           0 :   mRecorder->RecordEvent(RecordedPopLayer(static_cast<DrawTarget*>(this)));
     615           0 :   mFinalDT->PopLayer();
     616           0 : }
     617             : 
     618             : already_AddRefed<SourceSurface>
     619           0 : DrawTargetWrapAndRecord::CreateSourceSurfaceFromData(unsigned char *aData,
     620             :                                                  const IntSize &aSize,
     621             :                                                  int32_t aStride,
     622             :                                                  SurfaceFormat aFormat) const
     623             : {
     624           0 :   RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
     625             : 
     626           0 :   RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
     627             : 
     628           0 :   mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat));
     629             : 
     630           0 :   return retSurf.forget();
     631             : }
     632             : 
     633             : already_AddRefed<SourceSurface>
     634           0 : DrawTargetWrapAndRecord::OptimizeSourceSurface(SourceSurface *aSurface) const
     635             : {
     636           0 :   RefPtr<SourceSurface> surf = mFinalDT->OptimizeSourceSurface(aSurface);
     637             : 
     638           0 :   RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
     639             : 
     640           0 :   RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
     641             : 
     642           0 :   if (!dataSurf) {
     643             :     // Let's try get it off the original surface.
     644           0 :     dataSurf = aSurface->GetDataSurface();
     645             :   }
     646             : 
     647           0 :   StoreSourceSurface(mRecorder, retSurf, dataSurf, "OptimizeSourceSurface");
     648             : 
     649           0 :   return retSurf.forget();
     650             : }
     651             : 
     652             : already_AddRefed<SourceSurface>
     653           0 : DrawTargetWrapAndRecord::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
     654             : {
     655           0 :   RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromNativeSurface(aSurface);
     656             : 
     657           0 :   RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
     658             : 
     659           0 :   RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
     660           0 :   StoreSourceSurface(mRecorder, retSurf, dataSurf, "CreateSourceSurfaceFromNativeSurface");
     661             : 
     662           0 :   return retSurf.forget();
     663             : }
     664             : 
     665             : already_AddRefed<DrawTarget>
     666           0 : DrawTargetWrapAndRecord::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
     667             : {
     668             :   RefPtr<DrawTarget> similarDT =
     669           0 :     mFinalDT->CreateSimilarDrawTarget(aSize, aFormat);
     670           0 :   if (!similarDT) {
     671           0 :     return nullptr;
     672             :   }
     673             : 
     674           0 :   similarDT = new DrawTargetWrapAndRecord(this, similarDT);
     675           0 :   return similarDT.forget();
     676             : }
     677             : 
     678             : already_AddRefed<PathBuilder>
     679           0 : DrawTargetWrapAndRecord::CreatePathBuilder(FillRule aFillRule) const
     680             : {
     681           0 :   RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule);
     682           0 :   return MakeAndAddRef<PathBuilderRecording>(builder, aFillRule);
     683             : }
     684             : 
     685             : already_AddRefed<GradientStops>
     686           0 : DrawTargetWrapAndRecord::CreateGradientStops(GradientStop *aStops,
     687             :                                          uint32_t aNumStops,
     688             :                                          ExtendMode aExtendMode) const
     689             : {
     690           0 :   RefPtr<GradientStops> stops = mFinalDT->CreateGradientStops(aStops, aNumStops, aExtendMode);
     691             : 
     692           0 :   RefPtr<GradientStops> retStops = new GradientStopsWrapAndRecord(stops, mRecorder);
     693             : 
     694           0 :   mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode));
     695             : 
     696           0 :   return retStops.forget();
     697             : }
     698             : 
     699             : void
     700           0 : DrawTargetWrapAndRecord::SetTransform(const Matrix &aTransform)
     701             : {
     702           0 :   mRecorder->RecordEvent(RecordedSetTransform(this, aTransform));
     703           0 :   DrawTarget::SetTransform(aTransform);
     704           0 :   mFinalDT->SetTransform(aTransform);
     705           0 : }
     706             : 
     707             : already_AddRefed<PathRecording>
     708           0 : DrawTargetWrapAndRecord::EnsurePathStored(const Path *aPath)
     709             : {
     710           0 :   RefPtr<PathRecording> pathWrapAndRecord;
     711           0 :   if (aPath->GetBackendType() == BackendType::RECORDING) {
     712           0 :     pathWrapAndRecord = const_cast<PathRecording*>(static_cast<const PathRecording*>(aPath));
     713           0 :     if (mRecorder->HasStoredObject(aPath)) {
     714           0 :       return pathWrapAndRecord.forget();
     715             :     }
     716             :   } else {
     717           0 :     MOZ_ASSERT(!mRecorder->HasStoredObject(aPath));
     718           0 :     FillRule fillRule = aPath->GetFillRule();
     719           0 :     RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(fillRule);
     720             :     RefPtr<PathBuilderRecording> builderWrapAndRecord =
     721           0 :       new PathBuilderRecording(builder, fillRule);
     722           0 :     aPath->StreamToSink(builderWrapAndRecord);
     723           0 :     pathWrapAndRecord = builderWrapAndRecord->Finish().downcast<PathRecording>();
     724             :   }
     725             : 
     726           0 :   mRecorder->RecordEvent(RecordedPathCreation(pathWrapAndRecord.get()));
     727           0 :   mRecorder->AddStoredObject(pathWrapAndRecord);
     728           0 :   pathWrapAndRecord->mStoredRecorders.push_back(mRecorder);
     729             : 
     730           0 :   return pathWrapAndRecord.forget();
     731             : }
     732             : 
     733             : void
     734           0 : DrawTargetWrapAndRecord::EnsurePatternDependenciesStored(const Pattern &aPattern)
     735             : {
     736           0 :   switch (aPattern.GetType()) {
     737             :   case PatternType::COLOR:
     738             :     // No dependencies here.
     739           0 :     return;
     740             :   case PatternType::LINEAR_GRADIENT:
     741             :     {
     742           0 :       MOZ_ASSERT(mRecorder->HasStoredObject(static_cast<const LinearGradientPattern*>(&aPattern)->mStops));
     743           0 :       return;
     744             :     }
     745             :   case PatternType::RADIAL_GRADIENT:
     746             :     {
     747           0 :       MOZ_ASSERT(mRecorder->HasStoredObject(static_cast<const RadialGradientPattern*>(&aPattern)->mStops));
     748           0 :       return;
     749             :     }
     750             :   case PatternType::SURFACE:
     751             :     {
     752           0 :       const SurfacePattern *pat = static_cast<const SurfacePattern*>(&aPattern);
     753           0 :       EnsureSurfaceStored(mRecorder, pat->mSurface, "EnsurePatternDependenciesStored");
     754           0 :       return;
     755             :     }
     756             :   }
     757             : }
     758             : 
     759             : } // namespace gfx
     760             : } // namespace mozilla

Generated by: LCOV version 1.13