tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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