RecordedEvent.cpp (6862B)
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 #include "RecordedEventImpl.h" 8 9 #include "PathRecording.h" 10 #include "RecordingTypes.h" 11 #include "Tools.h" 12 #include "Filters.h" 13 #include "Logging.h" 14 #include "ScaledFontBase.h" 15 #include "SFNTData.h" 16 #include "InlineTranslator.h" 17 18 namespace mozilla { 19 namespace gfx { 20 21 /* static */ 22 bool RecordedEvent::DoWithEventFromStream( 23 EventStream& aStream, EventType aType, 24 const std::function<bool(RecordedEvent*)>& aAction) { 25 return DoWithEvent(aStream, aType, aAction); 26 } 27 28 /* static */ 29 bool RecordedEvent::DoWithEventFromReader( 30 MemReader& aReader, EventType aType, 31 const std::function<bool(RecordedEvent*)>& aAction) { 32 return DoWithEvent(aReader, aType, aAction); 33 } 34 35 std::string RecordedEvent::GetEventName(EventType aType) { 36 switch (aType) { 37 case DRAWTARGETCREATION: 38 return "DrawTarget Creation"; 39 case DRAWTARGETDESTRUCTION: 40 return "DrawTarget Destruction"; 41 case FILLRECT: 42 return "FillRect"; 43 case STROKERECT: 44 return "StrokeRect"; 45 case STROKELINE: 46 return "StrokeLine"; 47 case CLEARRECT: 48 return "ClearRect"; 49 case COPYSURFACE: 50 return "CopySurface"; 51 case SETPERMITSUBPIXELAA: 52 return "SetPermitSubpixelAA"; 53 case SETTRANSFORM: 54 return "SetTransform"; 55 case PUSHCLIP: 56 return "PushClip"; 57 case PUSHCLIPRECT: 58 return "PushClipRect"; 59 case POPCLIP: 60 return "PopClip"; 61 case REMOVEALLCLIPS: 62 return "RemoveAllClips"; 63 case FILL: 64 return "Fill"; 65 case FILLGLYPHS: 66 return "FillGlyphs"; 67 case STROKEGLYPHS: 68 return "StrokeGlyphs"; 69 case MASK: 70 return "Mask"; 71 case STROKE: 72 return "Stroke"; 73 case DRAWSURFACE: 74 return "DrawSurface"; 75 case DRAWSURFACEDESCRIPTOR: 76 return "DrawSurfaceDescriptor"; 77 case DRAWDEPENDENTSURFACE: 78 return "DrawDependentSurface"; 79 case DRAWSURFACEWITHSHADOW: 80 return "DrawSurfaceWithShadow"; 81 case DRAWFILTER: 82 return "DrawFilter"; 83 case PATHCREATION: 84 return "PathCreation"; 85 case PATHDESTRUCTION: 86 return "PathDestruction"; 87 case SOURCESURFACECREATION: 88 return "SourceSurfaceCreation"; 89 case SOURCESURFACEDESTRUCTION: 90 return "SourceSurfaceDestruction"; 91 case FILTERNODECREATION: 92 return "FilterNodeCreation"; 93 case FILTERNODEDESTRUCTION: 94 return "FilterNodeDestruction"; 95 case GRADIENTSTOPSCREATION: 96 return "GradientStopsCreation"; 97 case GRADIENTSTOPSDESTRUCTION: 98 return "GradientStopsDestruction"; 99 case SNAPSHOT: 100 return "Snapshot"; 101 case SCALEDFONTCREATION: 102 return "ScaledFontCreation"; 103 case SCALEDFONTDESTRUCTION: 104 return "ScaledFontDestruction"; 105 case MASKSURFACE: 106 return "MaskSurface"; 107 case FILTERNODESETATTRIBUTE: 108 return "SetAttribute"; 109 case FILTERNODESETINPUT: 110 return "SetInput"; 111 case CREATESIMILARDRAWTARGET: 112 return "CreateSimilarDrawTarget"; 113 case FONTDATA: 114 return "FontData"; 115 case FONTDESC: 116 return "FontDescriptor"; 117 case PUSHLAYER: 118 return "PushLayer"; 119 case POPLAYER: 120 return "PopLayer"; 121 case UNSCALEDFONTCREATION: 122 return "UnscaledFontCreation"; 123 case UNSCALEDFONTDESTRUCTION: 124 return "UnscaledFontDestruction"; 125 case EXTERNALSURFACECREATION: 126 return "ExternalSourceSurfaceCreation"; 127 case LINK: 128 return "Link"; 129 case DESTINATION: 130 return "Destination"; 131 default: 132 return "Unknown"; 133 } 134 } 135 136 template <class S> 137 void RecordedEvent::RecordUnscaledFontImpl(UnscaledFont* aUnscaledFont, 138 S& aOutput) { 139 RecordedFontData fontData(aUnscaledFont); 140 RecordedFontDetails fontDetails; 141 if (fontData.GetFontDetails(fontDetails)) { 142 // Try to serialise the whole font, just in case this is a web font that 143 // is not present on the system. 144 WriteElement(aOutput, fontData.mType); 145 fontData.RecordToStream(aOutput); 146 147 auto r = RecordedUnscaledFontCreation(aUnscaledFont, fontDetails); 148 WriteElement(aOutput, r.mType); 149 r.RecordToStream(aOutput); 150 } else { 151 // If that fails, record just the font description and try to load it from 152 // the system on the other side. 153 RecordedFontDescriptor fontDesc(aUnscaledFont); 154 if (fontDesc.IsValid()) { 155 WriteElement(aOutput, fontDesc.RecordedEvent::mType); 156 fontDesc.RecordToStream(aOutput); 157 } else { 158 gfxWarning() 159 << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont"; 160 } 161 } 162 } 163 164 void RecordedEvent::RecordUnscaledFont(UnscaledFont* aUnscaledFont, 165 std::ostream* aOutput) { 166 RecordUnscaledFontImpl(aUnscaledFont, *aOutput); 167 } 168 169 void RecordedEvent::RecordUnscaledFont(UnscaledFont* aUnscaledFont, 170 MemStream& aOutput) { 171 RecordUnscaledFontImpl(aUnscaledFont, aOutput); 172 } 173 174 already_AddRefed<DrawTarget> Translator::CreateDrawTarget( 175 ReferencePtr aRefPtr, const IntSize& aSize, SurfaceFormat aFormat) { 176 RefPtr<DrawTarget> newDT = 177 GetReferenceDrawTarget()->CreateSimilarDrawTarget(aSize, aFormat); 178 AddDrawTarget(aRefPtr, newDT); 179 return newDT.forget(); 180 } 181 182 void Translator::DrawDependentSurface(uint64_t aKey, const Rect& aRect) { 183 if (!mDependentSurfaces || !mCurrentDT) { 184 return; 185 } 186 187 RefPtr<RecordedDependentSurface> recordedSurface = 188 mDependentSurfaces->Get(aKey); 189 if (!recordedSurface) { 190 return; 191 } 192 193 // Construct a new translator, so we can recurse into translating this 194 // sub-recording into the same DT. Set an initial transform for the 195 // translator, so that all commands get moved into the rect we want to draw. 196 // 197 // Because the recording may have filtered out SetTransform calls with the 198 // same value, we need to call SetTransform here to ensure it gets called at 199 // least once with the translated matrix. 200 const Matrix oldTransform = mCurrentDT->GetTransform(); 201 202 Matrix dependentTransform = oldTransform; 203 dependentTransform.PreTranslate(aRect.TopLeft()); 204 205 mCurrentDT->PushClipRect(aRect); 206 mCurrentDT->SetTransform(dependentTransform); 207 208 { 209 InlineTranslator translator(mCurrentDT, nullptr); 210 translator.SetReferenceDrawTargetTransform(dependentTransform); 211 translator.SetDependentSurfaces(mDependentSurfaces); 212 translator.TranslateRecording((char*)recordedSurface->mRecording.mData, 213 recordedSurface->mRecording.mLen); 214 } 215 216 mCurrentDT->SetTransform(oldTransform); 217 mCurrentDT->PopClip(); 218 } 219 220 } // namespace gfx 221 } // namespace mozilla