no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / gfx / 2d / DrawEventRecorder.cpp
blob614472812a946ea2fdb7195a42f1a616adf7662f
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 void DrawEventRecorderPrivate::StoreExternalSurfaceRecording(
20 SourceSurface* aSurface, uint64_t aKey) {
21 RecordEvent(RecordedExternalSurfaceCreation(aSurface, aKey));
22 mExternalSurfaces.push_back(aSurface);
25 void DrawEventRecorderPrivate::StoreSourceSurfaceRecording(
26 SourceSurface* aSurface, const char* aReason) {
27 RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface();
28 IntSize surfaceSize = aSurface->GetSize();
29 Maybe<DataSourceSurface::ScopedMap> map;
30 if (dataSurf) {
31 map.emplace(dataSurf, DataSourceSurface::READ);
33 if (!dataSurf || !map->IsMapped() ||
34 !Factory::AllowedSurfaceSize(surfaceSize)) {
35 gfxWarning() << "Recording failed to record SourceSurface for " << aReason;
37 // If surface size is not allowed, replace with reasonable size.
38 if (!Factory::AllowedSurfaceSize(surfaceSize)) {
39 surfaceSize.width = std::min(surfaceSize.width, kReasonableSurfaceSize);
40 surfaceSize.height = std::min(surfaceSize.height, kReasonableSurfaceSize);
43 // Insert a dummy source surface.
44 int32_t stride = surfaceSize.width * BytesPerPixel(aSurface->GetFormat());
45 UniquePtr<uint8_t[]> sourceData =
46 MakeUniqueFallible<uint8_t[]>(stride * surfaceSize.height);
47 if (!sourceData) {
48 // If the surface is too big just create a 1 x 1 dummy.
49 surfaceSize.width = 1;
50 surfaceSize.height = 1;
51 stride = surfaceSize.width * BytesPerPixel(aSurface->GetFormat());
52 sourceData = MakeUnique<uint8_t[]>(stride * surfaceSize.height);
55 RecordEvent(RecordedSourceSurfaceCreation(aSurface, sourceData.get(),
56 stride, surfaceSize,
57 aSurface->GetFormat()));
58 return;
61 RecordEvent(RecordedSourceSurfaceCreation(
62 aSurface, map->GetData(), map->GetStride(), dataSurf->GetSize(),
63 dataSurf->GetFormat()));
66 void DrawEventRecorderPrivate::RecordSourceSurfaceDestruction(void* aSurface) {
67 RemoveSourceSurface(static_cast<SourceSurface*>(aSurface));
68 RemoveStoredObject(aSurface);
69 RecordEvent(RecordedSourceSurfaceDestruction(ReferencePtr(aSurface)));
72 void DrawEventRecorderPrivate::DecrementUnscaledFontRefCount(
73 const ReferencePtr aUnscaledFont) {
74 auto element = mUnscaledFontRefs.Lookup(aUnscaledFont);
75 MOZ_DIAGNOSTIC_ASSERT(element,
76 "DecrementUnscaledFontRefCount calls should balance "
77 "with IncrementUnscaledFontRefCount calls");
78 if (--element.Data() <= 0) {
79 RecordEvent(RecordedUnscaledFontDestruction(aUnscaledFont));
80 element.Remove();
84 void DrawEventRecorderMemory::RecordEvent(const RecordedEvent& aEvent) {
85 aEvent.RecordToStream(mOutputStream);
88 void DrawEventRecorderMemory::AddDependentSurface(uint64_t aDependencyId) {
89 mDependentSurfaces.Insert(aDependencyId);
92 nsTHashSet<uint64_t>&& DrawEventRecorderMemory::TakeDependentSurfaces() {
93 return std::move(mDependentSurfaces);
96 DrawEventRecorderMemory::DrawEventRecorderMemory() {
97 WriteHeader(mOutputStream);
100 DrawEventRecorderMemory::DrawEventRecorderMemory(
101 const SerializeResourcesFn& aFn)
102 : mSerializeCallback(aFn) {
103 mExternalFonts = !!mSerializeCallback;
104 WriteHeader(mOutputStream);
107 void DrawEventRecorderMemory::Flush() {}
109 void DrawEventRecorderMemory::FlushItem(IntRect aRect) {
110 MOZ_RELEASE_ASSERT(!aRect.IsEmpty());
111 // Detaching our existing resources will add some
112 // destruction events to our stream so we need to do that
113 // first.
114 DetachResources();
116 // See moz2d_renderer.rs for a description of the stream format
117 WriteElement(mIndex, mOutputStream.mLength);
119 // write out the fonts into the extra data section
120 mSerializeCallback(mOutputStream, mScaledFonts);
121 WriteElement(mIndex, mOutputStream.mLength);
123 WriteElement(mIndex, aRect.x);
124 WriteElement(mIndex, aRect.y);
125 WriteElement(mIndex, aRect.XMost());
126 WriteElement(mIndex, aRect.YMost());
127 ClearResources();
129 // write out a new header for the next recording in the stream
130 WriteHeader(mOutputStream);
133 bool DrawEventRecorderMemory::Finish() {
134 // this length might be 0, and things should still work.
135 // for example if there are no items in a particular area
136 size_t indexOffset = mOutputStream.mLength;
137 // write out the index
138 mOutputStream.write(mIndex.mData, mIndex.mLength);
139 bool hasItems = mIndex.mLength != 0;
140 mIndex.reset();
141 // write out the offset of the Index to the end of the output stream
142 WriteElement(mOutputStream, indexOffset);
143 ClearResources();
144 return hasItems;
147 size_t DrawEventRecorderMemory::RecordingSize() {
148 return mOutputStream.mLength;
151 void DrawEventRecorderMemory::WipeRecording() {
152 mOutputStream.reset();
153 mIndex.reset();
155 WriteHeader(mOutputStream);
158 } // namespace gfx
159 } // namespace mozilla