DrawEventRecorder.cpp (6027B)
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 "DrawEventRecorder.h" 8 9 #include "PathRecording.h" 10 #include "RecordingTypes.h" 11 #include "RecordedEventImpl.h" 12 13 namespace mozilla { 14 namespace gfx { 15 16 DrawEventRecorderPrivate::DrawEventRecorderPrivate() : mExternalFonts(false) {} 17 18 DrawEventRecorderPrivate::~DrawEventRecorderPrivate() = default; 19 20 void DrawEventRecorderPrivate::SetDrawTarget(ReferencePtr aDT) { 21 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); 22 23 RecordEvent(RecordedSetCurrentDrawTarget(aDT)); 24 mCurrentDT = aDT; 25 } 26 27 void DrawEventRecorderPrivate::StoreExternalSurfaceRecording( 28 SourceSurface* aSurface, uint64_t aKey) { 29 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); 30 31 RecordEvent(RecordedExternalSurfaceCreation(aSurface, aKey)); 32 mExternalSurfaces.push_back({aSurface}); 33 } 34 35 void DrawEventRecorderPrivate::StoreExternalImageRecording( 36 const RefPtr<layers::Image>& aImageOfSurfaceDescriptor) { 37 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); 38 39 mExternalImages.push_back({aImageOfSurfaceDescriptor}); 40 } 41 42 void DrawEventRecorderPrivate::StoreSourceSurfaceRecording( 43 SourceSurface* aSurface, const char* aReason) { 44 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); 45 46 RefPtr<DataSourceSurface> dataSurf; 47 IntSize surfaceSize = aSurface->GetSize(); 48 if (Factory::AllowedSurfaceSize(surfaceSize)) { 49 dataSurf = aSurface->GetDataSurface(); 50 } 51 if (!dataSurf) { 52 gfxWarning() << "Recording failed to record SourceSurface for " << aReason; 53 54 // If surface size is not allowed, replace with reasonable size. 55 surfaceSize.width = std::min(surfaceSize.width, kReasonableSurfaceSize); 56 surfaceSize.height = std::min(surfaceSize.height, kReasonableSurfaceSize); 57 58 // Insert a dummy source surface. 59 if (Factory::AllowedSurfaceSize(surfaceSize)) { 60 dataSurf = Factory::CreateDataSourceSurface(surfaceSize, 61 aSurface->GetFormat(), true); 62 } 63 if (!dataSurf) { 64 // If the surface is too big just create a 1 x 1 dummy. 65 dataSurf = Factory::CreateDataSourceSurface(IntSize(1, 1), 66 aSurface->GetFormat(), true); 67 if (!dataSurf) { 68 return; 69 } 70 } 71 } 72 73 RecordEvent(RecordedSourceSurfaceCreation(aSurface, dataSurf)); 74 } 75 76 void DrawEventRecorderPrivate::RecordSourceSurfaceDestruction(void* aSurface) { 77 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); 78 79 RemoveSourceSurface(static_cast<SourceSurface*>(aSurface)); 80 RemoveStoredObject(aSurface); 81 RecordEvent(RecordedSourceSurfaceDestruction(ReferencePtr(aSurface))); 82 } 83 84 void DrawEventRecorderPrivate::DecrementUnscaledFontRefCount( 85 const ReferencePtr aUnscaledFont) { 86 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); 87 88 auto element = mUnscaledFontRefs.Lookup(aUnscaledFont); 89 MOZ_DIAGNOSTIC_ASSERT(element, 90 "DecrementUnscaledFontRefCount calls should balance " 91 "with IncrementUnscaledFontRefCount calls"); 92 if (--element.Data() <= 0) { 93 RecordEvent(RecordedUnscaledFontDestruction(aUnscaledFont)); 94 element.Remove(); 95 } 96 } 97 98 void DrawEventRecorderMemory::RecordEvent(const RecordedEvent& aEvent) { 99 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 100 aEvent.RecordToStream(mOutputStream); 101 } 102 103 void DrawEventRecorderMemory::AddDependentSurface(uint64_t aDependencyId) { 104 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 105 mDependentSurfaces.Insert(aDependencyId); 106 } 107 108 nsTHashSet<uint64_t>&& DrawEventRecorderMemory::TakeDependentSurfaces() { 109 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 110 return std::move(mDependentSurfaces); 111 } 112 113 DrawEventRecorderMemory::DrawEventRecorderMemory() { 114 WriteHeader(mOutputStream); 115 } 116 117 DrawEventRecorderMemory::DrawEventRecorderMemory( 118 const SerializeResourcesFn& aFn) 119 : mSerializeCallback(aFn) { 120 mExternalFonts = !!mSerializeCallback; 121 WriteHeader(mOutputStream); 122 } 123 124 void DrawEventRecorderMemory::Flush() { 125 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 126 } 127 128 void DrawEventRecorderMemory::FlushItem(IntRect aRect) { 129 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 130 131 MOZ_RELEASE_ASSERT(!aRect.IsEmpty()); 132 // Detaching our existing resources will add some 133 // destruction events to our stream so we need to do that 134 // first. 135 DetachResources(); 136 137 // See moz2d_renderer.rs for a description of the stream format 138 WriteElement(mIndex, mOutputStream.mLength); 139 140 // write out the fonts into the extra data section 141 mSerializeCallback(mOutputStream, mScaledFonts); 142 WriteElement(mIndex, mOutputStream.mLength); 143 144 WriteElement(mIndex, aRect.x); 145 WriteElement(mIndex, aRect.y); 146 WriteElement(mIndex, aRect.XMost()); 147 WriteElement(mIndex, aRect.YMost()); 148 ClearResources(); 149 150 // write out a new header for the next recording in the stream 151 WriteHeader(mOutputStream); 152 } 153 154 bool DrawEventRecorderMemory::Finish() { 155 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 156 157 // this length might be 0, and things should still work. 158 // for example if there are no items in a particular area 159 size_t indexOffset = mOutputStream.mLength; 160 // write out the index 161 mOutputStream.write(mIndex.mData, mIndex.mLength); 162 bool hasItems = mIndex.mLength != 0; 163 mIndex.reset(); 164 // write out the offset of the Index to the end of the output stream 165 WriteElement(mOutputStream, indexOffset); 166 ClearResources(); 167 return hasItems; 168 } 169 170 size_t DrawEventRecorderMemory::RecordingSize() { 171 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 172 return mOutputStream.mLength; 173 } 174 175 void DrawEventRecorderMemory::WipeRecording() { 176 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory); 177 178 mOutputStream.reset(); 179 mIndex.reset(); 180 181 WriteHeader(mOutputStream); 182 } 183 184 } // namespace gfx 185 } // namespace mozilla