tor-browser

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

TextureRecorded.cpp (7090B)


      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 "TextureRecorded.h"
      8 #include "mozilla/gfx/DrawTargetRecording.h"
      9 #include "mozilla/layers/CompositableForwarder.h"
     10 
     11 #include "RecordedCanvasEventImpl.h"
     12 
     13 namespace mozilla {
     14 namespace layers {
     15 
     16 RecordedTextureData::RecordedTextureData(
     17    already_AddRefed<CanvasChild> aCanvasChild, gfx::IntSize aSize,
     18    gfx::SurfaceFormat aFormat, TextureType aTextureType,
     19    TextureType aWebglTextureType)
     20    : mRemoteTextureOwnerId(RemoteTextureOwnerId::GetNext()),
     21      mCanvasChild(aCanvasChild),
     22      mSize(aSize),
     23      mFormat(aFormat) {}
     24 
     25 RecordedTextureData::~RecordedTextureData() {
     26  // We need the translator to drop its reference for the DrawTarget first,
     27  // because the TextureData might need to destroy its DrawTarget within a lock.
     28  mSnapshot = nullptr;
     29  DetachSnapshotWrapper();
     30  if (mDT) {
     31    mDT->DetachTextureData(this);
     32    mDT = nullptr;
     33  }
     34  mCanvasChild->RecordEvent(RecordedTextureDestruction(
     35      mRemoteTextureOwnerId, ToRemoteTextureTxnType(mFwdTransactionTracker),
     36      ToRemoteTextureTxnId(mFwdTransactionTracker)));
     37 }
     38 
     39 void RecordedTextureData::FillInfo(TextureData::Info& aInfo) const {
     40  aInfo.size = mSize;
     41  aInfo.format = mFormat;
     42  aInfo.supportsMoz2D = true;
     43  aInfo.hasSynchronization = true;
     44 }
     45 
     46 void RecordedTextureData::InvalidateContents() { mInvalidContents = true; }
     47 
     48 bool RecordedTextureData::Lock(OpenMode aMode) {
     49  if (!mCanvasChild->EnsureBeginTransaction()) {
     50    return false;
     51  }
     52 
     53  if (!mDT && mInited) {
     54    return false;
     55  }
     56 
     57  // If modifying the texture, then allocate a new remote texture id.
     58  if (aMode & OpenMode::OPEN_WRITE) {
     59    mUsedRemoteTexture = false;
     60  }
     61 
     62  bool wasInvalidContents = mInvalidContents;
     63  mInvalidContents = false;
     64 
     65  if (!mDT && !mInited) {
     66    mInited = true;
     67    mDT = mCanvasChild->CreateDrawTarget(mRemoteTextureOwnerId, mSize, mFormat);
     68    if (!mDT) {
     69      return false;
     70    }
     71 
     72    mDT->AttachTextureData(this);
     73 
     74    // We lock the TextureData when we create it to get the remote DrawTarget.
     75    mLockedMode = aMode;
     76    return true;
     77  }
     78 
     79  mCanvasChild->RecordEvent(
     80      RecordedTextureLock(mRemoteTextureOwnerId, aMode, wasInvalidContents));
     81  mLockedMode = aMode;
     82  return true;
     83 }
     84 
     85 void RecordedTextureData::DetachSnapshotWrapper(bool aInvalidate,
     86                                                bool aRelease) {
     87  if (mSnapshotWrapper) {
     88    // If the snapshot only has one ref, then we don't need to worry about
     89    // copying before invalidation since it is about to be deleted. Otherwise,
     90    // we need to ensure any internal data is appropriately copied before
     91    // shmems are potentially overwritten if there are still existing users.
     92    mCanvasChild->DetachSurface(mSnapshotWrapper,
     93                                aInvalidate && !mSnapshotWrapper->hasOneRef());
     94    if (aRelease) {
     95      mSnapshotWrapper = nullptr;
     96    }
     97  }
     98 }
     99 
    100 void RecordedTextureData::Unlock() {
    101  if ((mLockedMode == OpenMode::OPEN_READ_WRITE) &&
    102      mCanvasChild->ShouldCacheDataSurface()) {
    103    DetachSnapshotWrapper();
    104    mSnapshot = mDT->Snapshot();
    105    mDT->DetachAllSnapshots();
    106    mCanvasChild->RecordEvent(RecordedCacheDataSurface(mSnapshot.get()));
    107  }
    108 
    109  mCanvasChild->RecordEvent(RecordedTextureUnlock(mRemoteTextureOwnerId));
    110 
    111  mLockedMode = OpenMode::OPEN_NONE;
    112 }
    113 
    114 already_AddRefed<gfx::DrawTarget> RecordedTextureData::BorrowDrawTarget() {
    115  if (mLockedMode & OpenMode::OPEN_WRITE) {
    116    // The snapshot will be invalidated.
    117    mSnapshot = nullptr;
    118    DetachSnapshotWrapper(true);
    119  }
    120  return do_AddRef(mDT);
    121 }
    122 
    123 void RecordedTextureData::EndDraw() {
    124  MOZ_ASSERT(mDT->hasOneRef());
    125  MOZ_ASSERT(mLockedMode == OpenMode::OPEN_READ_WRITE);
    126 
    127  if (mCanvasChild->ShouldCacheDataSurface()) {
    128    DetachSnapshotWrapper();
    129    mSnapshot = mDT->Snapshot();
    130    mCanvasChild->RecordEvent(RecordedCacheDataSurface(mSnapshot.get()));
    131  }
    132 }
    133 
    134 void RecordedTextureData::DrawTargetWillChange() {
    135  // The DrawTargetRecording will be modified, so ensure that possibly the last
    136  // reference to a snapshot is discarded so that it does not inadvertently
    137  // force a copy.
    138  mSnapshot = nullptr;
    139  DetachSnapshotWrapper(true);
    140 }
    141 
    142 already_AddRefed<gfx::SourceSurface> RecordedTextureData::BorrowSnapshot() {
    143  if (mSnapshotWrapper) {
    144    // The DT is unmodified since the last time snapshot was borrowed, so it
    145    // is safe to reattach the snapshot for shmem readbacks.
    146    mCanvasChild->AttachSurface(mSnapshotWrapper);
    147    return do_AddRef(mSnapshotWrapper);
    148  }
    149 
    150  // There are some failure scenarios where we have no DrawTarget and
    151  // BorrowSnapshot is called in an attempt to copy to a new texture.
    152  if (!mDT) {
    153    return nullptr;
    154  }
    155 
    156  RefPtr<gfx::SourceSurface> wrapper = mCanvasChild->WrapSurface(
    157      mSnapshot ? mSnapshot : mDT->Snapshot(), mRemoteTextureOwnerId);
    158  mSnapshotWrapper = wrapper;
    159  return wrapper.forget();
    160 }
    161 
    162 void RecordedTextureData::ReturnDrawTarget(
    163    already_AddRefed<gfx::DrawTarget> aDT) {
    164  RefPtr<gfx::DrawTarget> dt(aDT);
    165 }
    166 
    167 void RecordedTextureData::ReturnSnapshot(
    168    already_AddRefed<gfx::SourceSurface> aSnapshot) {
    169  RefPtr<gfx::SourceSurface> snapshot = aSnapshot;
    170  // The snapshot needs to be marked detached but we keep the wrapper around
    171  // so that it can be reused without repeatedly creating it and accidentally
    172  // reading back data for each new instantiation.
    173  DetachSnapshotWrapper(false, false);
    174 }
    175 
    176 void RecordedTextureData::Deallocate(LayersIPCChannel* aAllocator) {}
    177 
    178 bool RecordedTextureData::Serialize(SurfaceDescriptor& aDescriptor) {
    179  // If something is querying the id, assume it is going to be composited.
    180  if (!mUsedRemoteTexture) {
    181    mLastRemoteTextureId = RemoteTextureId::GetNext();
    182    mCanvasChild->RecordEvent(
    183        RecordedPresentTexture(mRemoteTextureOwnerId, mLastRemoteTextureId));
    184    mUsedRemoteTexture = true;
    185  }
    186 
    187  aDescriptor = SurfaceDescriptorRemoteTexture(mLastRemoteTextureId,
    188                                               mRemoteTextureOwnerId);
    189  return true;
    190 }
    191 
    192 already_AddRefed<FwdTransactionTracker>
    193 RecordedTextureData::UseCompositableForwarder(
    194    CompositableForwarder* aForwarder) {
    195  return FwdTransactionTracker::GetOrCreate(mFwdTransactionTracker);
    196 }
    197 
    198 void RecordedTextureData::OnForwardedToHost() {
    199  // Compositing with RecordedTextureData requires RemoteTextureMap.
    200  MOZ_CRASH("OnForwardedToHost not supported!");
    201 }
    202 
    203 TextureFlags RecordedTextureData::GetTextureFlags() const {
    204  // With WebRender, resource open happens asynchronously on RenderThread.
    205  // Use WAIT_HOST_USAGE_END to keep TextureClient alive during host side usage.
    206  return TextureFlags::WAIT_HOST_USAGE_END;
    207 }
    208 
    209 bool RecordedTextureData::RequiresRefresh() const {
    210  return mCanvasChild->RequiresRefresh(mRemoteTextureOwnerId);
    211 }
    212 
    213 }  // namespace layers
    214 }  // namespace mozilla