tor-browser

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

CompositionRecorder.cpp (3114B)


      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 "CompositionRecorder.h"
      8 #include "gfxUtils.h"
      9 #include "mozilla/gfx/2D.h"
     10 #include "mozilla/gfx/gfxVars.h"
     11 #include "nsIInputStream.h"
     12 #include "nsIBinaryOutputStream.h"
     13 #include "nsIObjectOutputStream.h"
     14 #include "prtime.h"
     15 
     16 #include <ctime>
     17 #include <iomanip>
     18 #include "stdio.h"
     19 #ifdef XP_WIN
     20 #  include "direct.h"
     21 #else
     22 #  include <sys/types.h>
     23 #  include "sys/stat.h"
     24 #endif
     25 
     26 using namespace mozilla::gfx;
     27 
     28 namespace mozilla {
     29 namespace layers {
     30 
     31 CompositionRecorder::CompositionRecorder(TimeStamp aRecordingStart)
     32    : mRecordingStart(aRecordingStart) {}
     33 
     34 void CompositionRecorder::RecordFrame(RecordedFrame* aFrame) {
     35  mRecordedFrames.AppendElement(aFrame);
     36 }
     37 
     38 Maybe<FrameRecording> CompositionRecorder::GetRecording() {
     39  FrameRecording recording;
     40 
     41  recording.startTime() = mRecordingStart;
     42 
     43  nsTArray<uint8_t> bytes;
     44  for (RefPtr<RecordedFrame>& recordedFrame : mRecordedFrames) {
     45    RefPtr<DataSourceSurface> surf = recordedFrame->GetSourceSurface();
     46    if (!surf) {
     47      return Nothing();
     48    }
     49 
     50    nsCOMPtr<nsIInputStream> imgStream;
     51    nsresult rv = gfxUtils::EncodeSourceSurfaceAsStream(
     52        surf, ImageType::PNG, u""_ns, getter_AddRefs(imgStream));
     53    if (NS_FAILED(rv)) {
     54      return Nothing();
     55    }
     56 
     57    uint64_t bufSize64;
     58    rv = imgStream->Available(&bufSize64);
     59    if (NS_FAILED(rv) || bufSize64 > UINT32_MAX) {
     60      return Nothing();
     61    }
     62 
     63    const uint32_t frameLength = static_cast<uint32_t>(bufSize64);
     64    size_t startIndex = bytes.Length();
     65    bytes.SetLength(startIndex + frameLength);
     66 
     67    uint8_t* bytePtr = &bytes[startIndex];
     68    uint32_t bytesLeft = frameLength;
     69 
     70    while (bytesLeft > 0) {
     71      uint32_t bytesRead = 0;
     72      rv = imgStream->Read(reinterpret_cast<char*>(bytePtr), bytesLeft,
     73                           &bytesRead);
     74      if (NS_FAILED(rv) || bytesRead == 0) {
     75        return Nothing();
     76      }
     77 
     78      bytePtr += bytesRead;
     79      bytesLeft -= bytesRead;
     80    }
     81 
     82 #ifdef DEBUG
     83 
     84    // Currently, all implementers of imgIEncoder report their exact size
     85    // through nsIInputStream::Available(), but let's explicitly state that we
     86    // rely on that behavior for the algorithm above.
     87 
     88    char dummy = 0;
     89    uint32_t bytesRead = 0;
     90    rv = imgStream->Read(&dummy, 1, &bytesRead);
     91    MOZ_ASSERT(NS_SUCCEEDED(rv) && bytesRead == 0);
     92 
     93 #endif
     94 
     95    RecordedFrameData frameData;
     96 
     97    frameData.timeOffset() = recordedFrame->GetTimeStamp();
     98    frameData.length() = frameLength;
     99 
    100    recording.frames().AppendElement(std::move(frameData));
    101 
    102    // Now that we're done, release the frame so we can free up its memory
    103    recordedFrame = nullptr;
    104  }
    105 
    106  mRecordedFrames.Clear();
    107 
    108  recording.bytes() = ipc::BigBuffer(bytes);
    109 
    110  return Some(std::move(recording));
    111 }
    112 
    113 }  // namespace layers
    114 }  // namespace mozilla