no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / gfx / 2d / DrawEventRecorder.cpp
blob51f8b836eccfee6dd2377284e851b6f0bd7fdc61
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/. */
7 #include "DrawEventRecorder.h"
9 #include "mozilla/UniquePtrExtensions.h"
10 #include "PathRecording.h"
11 #include "RecordingTypes.h"
12 #include "RecordedEventImpl.h"
14 namespace mozilla {
15 namespace gfx {
17 DrawEventRecorderPrivate::DrawEventRecorderPrivate() : mExternalFonts(false) {}
19 DrawEventRecorderPrivate::~DrawEventRecorderPrivate() = default;
21 void DrawEventRecorderPrivate::SetDrawTarget(ReferencePtr aDT) {
22 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
24 RecordEvent(RecordedSetCurrentDrawTarget(aDT));
25 mCurrentDT = aDT;
28 void DrawEventRecorderPrivate::StoreExternalSurfaceRecording(
29 SourceSurface* aSurface, uint64_t aKey) {
30 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
32 RecordEvent(RecordedExternalSurfaceCreation(aSurface, aKey));
33 mExternalSurfaces.push_back({aSurface});
36 void DrawEventRecorderPrivate::StoreSourceSurfaceRecording(
37 SourceSurface* aSurface, const char* aReason) {
38 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
40 RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface();
41 IntSize surfaceSize = aSurface->GetSize();
42 Maybe<DataSourceSurface::ScopedMap> map;
43 if (dataSurf) {
44 map.emplace(dataSurf, DataSourceSurface::READ);
46 if (!dataSurf || !map->IsMapped() ||
47 !Factory::AllowedSurfaceSize(surfaceSize)) {
48 gfxWarning() << "Recording failed to record SourceSurface for " << aReason;
50 // If surface size is not allowed, replace with reasonable size.
51 if (!Factory::AllowedSurfaceSize(surfaceSize)) {
52 surfaceSize.width = std::min(surfaceSize.width, kReasonableSurfaceSize);
53 surfaceSize.height = std::min(surfaceSize.height, kReasonableSurfaceSize);
56 // Insert a dummy source surface.
57 int32_t stride = surfaceSize.width * BytesPerPixel(aSurface->GetFormat());
58 UniquePtr<uint8_t[]> sourceData =
59 MakeUniqueFallible<uint8_t[]>(stride * surfaceSize.height);
60 if (!sourceData) {
61 // If the surface is too big just create a 1 x 1 dummy.
62 surfaceSize.width = 1;
63 surfaceSize.height = 1;
64 stride = surfaceSize.width * BytesPerPixel(aSurface->GetFormat());
65 sourceData = MakeUnique<uint8_t[]>(stride * surfaceSize.height);
68 RecordEvent(RecordedSourceSurfaceCreation(aSurface, sourceData.get(),
69 stride, surfaceSize,
70 aSurface->GetFormat()));
71 return;
74 RecordEvent(RecordedSourceSurfaceCreation(
75 aSurface, map->GetData(), map->GetStride(), dataSurf->GetSize(),
76 dataSurf->GetFormat()));
79 void DrawEventRecorderPrivate::RecordSourceSurfaceDestruction(void* aSurface) {
80 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
82 RemoveSourceSurface(static_cast<SourceSurface*>(aSurface));
83 RemoveStoredObject(aSurface);
84 RecordEvent(RecordedSourceSurfaceDestruction(ReferencePtr(aSurface)));
87 void DrawEventRecorderPrivate::DecrementUnscaledFontRefCount(
88 const ReferencePtr aUnscaledFont) {
89 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate);
91 auto element = mUnscaledFontRefs.Lookup(aUnscaledFont);
92 MOZ_DIAGNOSTIC_ASSERT(element,
93 "DecrementUnscaledFontRefCount calls should balance "
94 "with IncrementUnscaledFontRefCount calls");
95 if (--element.Data() <= 0) {
96 RecordEvent(RecordedUnscaledFontDestruction(aUnscaledFont));
97 element.Remove();
101 void DrawEventRecorderMemory::RecordEvent(const RecordedEvent& aEvent) {
102 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
103 aEvent.RecordToStream(mOutputStream);
106 void DrawEventRecorderMemory::AddDependentSurface(uint64_t aDependencyId) {
107 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
108 mDependentSurfaces.Insert(aDependencyId);
111 nsTHashSet<uint64_t>&& DrawEventRecorderMemory::TakeDependentSurfaces() {
112 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
113 return std::move(mDependentSurfaces);
116 DrawEventRecorderMemory::DrawEventRecorderMemory() {
117 WriteHeader(mOutputStream);
120 DrawEventRecorderMemory::DrawEventRecorderMemory(
121 const SerializeResourcesFn& aFn)
122 : mSerializeCallback(aFn) {
123 mExternalFonts = !!mSerializeCallback;
124 WriteHeader(mOutputStream);
127 void DrawEventRecorderMemory::Flush() {
128 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
131 void DrawEventRecorderMemory::FlushItem(IntRect aRect) {
132 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
134 MOZ_RELEASE_ASSERT(!aRect.IsEmpty());
135 // Detaching our existing resources will add some
136 // destruction events to our stream so we need to do that
137 // first.
138 DetachResources();
140 // See moz2d_renderer.rs for a description of the stream format
141 WriteElement(mIndex, mOutputStream.mLength);
143 // write out the fonts into the extra data section
144 mSerializeCallback(mOutputStream, mScaledFonts);
145 WriteElement(mIndex, mOutputStream.mLength);
147 WriteElement(mIndex, aRect.x);
148 WriteElement(mIndex, aRect.y);
149 WriteElement(mIndex, aRect.XMost());
150 WriteElement(mIndex, aRect.YMost());
151 ClearResources();
153 // write out a new header for the next recording in the stream
154 WriteHeader(mOutputStream);
157 bool DrawEventRecorderMemory::Finish() {
158 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
160 // this length might be 0, and things should still work.
161 // for example if there are no items in a particular area
162 size_t indexOffset = mOutputStream.mLength;
163 // write out the index
164 mOutputStream.write(mIndex.mData, mIndex.mLength);
165 bool hasItems = mIndex.mLength != 0;
166 mIndex.reset();
167 // write out the offset of the Index to the end of the output stream
168 WriteElement(mOutputStream, indexOffset);
169 ClearResources();
170 return hasItems;
173 size_t DrawEventRecorderMemory::RecordingSize() {
174 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
175 return mOutputStream.mLength;
178 void DrawEventRecorderMemory::WipeRecording() {
179 NS_ASSERT_OWNINGTHREAD(DrawEventRecorderMemory);
181 mOutputStream.reset();
182 mIndex.reset();
184 WriteHeader(mOutputStream);
187 } // namespace gfx
188 } // namespace mozilla