tor-browser

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

WebRenderTextureHost.cpp (7476B)


      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 "WebRenderTextureHost.h"
      8 
      9 #include "mozilla/layers/ImageDataSerializer.h"
     10 #include "mozilla/layers/LayersSurfaces.h"
     11 #include "mozilla/layers/TextureSourceProvider.h"
     12 #include "mozilla/webrender/RenderThread.h"
     13 #include "mozilla/webrender/WebRenderAPI.h"
     14 
     15 #ifdef MOZ_WIDGET_ANDROID
     16 #  include "mozilla/layers/TextureHostOGL.h"
     17 #endif
     18 
     19 #ifdef XP_WIN
     20 #  include "mozilla/layers/TextureD3D11.h"
     21 #endif
     22 
     23 namespace mozilla::layers {
     24 
     25 class ScheduleHandleRenderTextureOps : public wr::NotificationHandler {
     26 public:
     27  explicit ScheduleHandleRenderTextureOps() {}
     28 
     29  virtual void Notify(wr::Checkpoint aCheckpoint) override {
     30    if (aCheckpoint == wr::Checkpoint::FrameTexturesUpdated) {
     31      MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
     32      wr::RenderThread::Get()->HandleRenderTextureOps();
     33    } else {
     34      MOZ_ASSERT(aCheckpoint == wr::Checkpoint::TransactionDropped);
     35    }
     36  }
     37 
     38 protected:
     39 };
     40 
     41 WebRenderTextureHost::WebRenderTextureHost(
     42    TextureFlags aFlags, TextureHost* aTexture,
     43    const wr::ExternalImageId& aExternalImageId)
     44    : TextureHost(TextureHostType::Unknown, aFlags),
     45      mWrappedTextureHost(aTexture) {
     46  MOZ_ASSERT(mWrappedTextureHost);
     47  // The wrapped textureHost will be used in WebRender, and the WebRender could
     48  // run at another thread. It's hard to control the life-time when gecko
     49  // receives PTextureParent destroy message. It's possible that textureHost is
     50  // still used by WebRender. So, we only accept the textureHost without
     51  // DEALLOCATE_CLIENT flag here. If the buffer deallocation is controlled by
     52  // parent, we could do something to make sure the wrapped textureHost is not
     53  // used by WebRender and then release it.
     54  MOZ_ASSERT(!(aFlags & TextureFlags::DEALLOCATE_CLIENT));
     55  MOZ_COUNT_CTOR(WebRenderTextureHost);
     56 
     57  mExternalImageId = Some(aExternalImageId);
     58 }
     59 
     60 WebRenderTextureHost::~WebRenderTextureHost() {
     61  MOZ_COUNT_DTOR(WebRenderTextureHost);
     62 }
     63 
     64 wr::ExternalImageId WebRenderTextureHost::GetExternalImageKey() {
     65  if (IsValid()) {
     66    mWrappedTextureHost->EnsureRenderTexture(mExternalImageId);
     67  }
     68  MOZ_ASSERT(mWrappedTextureHost->mExternalImageId.isSome());
     69  return mWrappedTextureHost->mExternalImageId.ref();
     70 }
     71 
     72 bool WebRenderTextureHost::IsValid() { return mWrappedTextureHost->IsValid(); }
     73 
     74 void WebRenderTextureHost::UnbindTextureSource() {
     75  if (mWrappedTextureHost->AsBufferTextureHost()) {
     76    mWrappedTextureHost->UnbindTextureSource();
     77  }
     78  // Handle read unlock
     79  TextureHost::UnbindTextureSource();
     80 }
     81 
     82 already_AddRefed<gfx::DataSourceSurface> WebRenderTextureHost::GetAsSurface(
     83    gfx::DataSourceSurface* aSurface) {
     84  return mWrappedTextureHost->GetAsSurface(aSurface);
     85 }
     86 
     87 gfx::ColorDepth WebRenderTextureHost::GetColorDepth() const {
     88  return mWrappedTextureHost->GetColorDepth();
     89 }
     90 
     91 gfx::YUVColorSpace WebRenderTextureHost::GetYUVColorSpace() const {
     92  return mWrappedTextureHost->GetYUVColorSpace();
     93 }
     94 
     95 gfx::ColorRange WebRenderTextureHost::GetColorRange() const {
     96  return mWrappedTextureHost->GetColorRange();
     97 }
     98 
     99 gfx::IntSize WebRenderTextureHost::GetSize() const {
    100  return mWrappedTextureHost->GetSize();
    101 }
    102 
    103 gfx::SurfaceFormat WebRenderTextureHost::GetFormat() const {
    104  return mWrappedTextureHost->GetFormat();
    105 }
    106 
    107 bool WebRenderTextureHost::NeedsYFlip() const {
    108  return mWrappedTextureHost->NeedsYFlip();
    109 }
    110 
    111 void WebRenderTextureHost::MaybeDestroyRenderTexture() {
    112  // WebRenderTextureHost does not create RenderTexture, then
    113  // WebRenderTextureHost does not need to destroy RenderTexture.
    114  mExternalImageId = Nothing();
    115 }
    116 
    117 void WebRenderTextureHost::NotifyNotUsed() {
    118 #ifdef MOZ_WIDGET_ANDROID
    119  // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
    120  // NotifyNotUsed() is handled by SurfaceTextureHost.
    121  if (IsWrappingSurfaceTextureHost() &&
    122      !mWrappedTextureHost->AsRemoteTextureHostWrapper()) {
    123    wr::RenderThread::Get()->NotifyNotUsed(GetExternalImageKey());
    124  }
    125 #endif
    126  mWrappedTextureHost->NotifyNotUsed();
    127  TextureHost::NotifyNotUsed();
    128 }
    129 
    130 void WebRenderTextureHost::MaybeNotifyForUse(wr::TransactionBuilder& aTxn) {
    131 #if defined(MOZ_WIDGET_ANDROID)
    132  if (IsWrappingSurfaceTextureHost() &&
    133      !mWrappedTextureHost->AsRemoteTextureHostWrapper()) {
    134    wr::RenderThread::Get()->NotifyForUse(GetExternalImageKey());
    135    aTxn.Notify(wr::Checkpoint::FrameTexturesUpdated,
    136                MakeUnique<ScheduleHandleRenderTextureOps>());
    137  }
    138 #endif
    139 }
    140 
    141 bool WebRenderTextureHost::IsWrappingSurfaceTextureHost() {
    142  return mWrappedTextureHost->IsWrappingSurfaceTextureHost();
    143 }
    144 
    145 void WebRenderTextureHost::PrepareForUse() {
    146  // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
    147  // PrepareForUse() is handled by SurfaceTextureHost.
    148  if ((IsWrappingSurfaceTextureHost() &&
    149       !mWrappedTextureHost->AsRemoteTextureHostWrapper()) ||
    150      mWrappedTextureHost->AsBufferTextureHost()) {
    151    // Call PrepareForUse on render thread.
    152    // See RenderAndroidSurfaceTextureHostOGL::PrepareForUse.
    153    wr::RenderThread::Get()->PrepareForUse(GetExternalImageKey());
    154  }
    155 }
    156 
    157 gfx::SurfaceFormat WebRenderTextureHost::GetReadFormat() const {
    158  return mWrappedTextureHost->GetReadFormat();
    159 }
    160 
    161 int32_t WebRenderTextureHost::GetRGBStride() {
    162  gfx::SurfaceFormat format = GetFormat();
    163  if (GetFormat() == gfx::SurfaceFormat::YUV420) {
    164    // XXX this stride is used until yuv image rendering by webrender is used.
    165    // Software converted RGB buffers strides are aliened to 16
    166    return gfx::GetAlignedStride<16>(
    167        GetSize().width, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8));
    168  }
    169  return ImageDataSerializer::ComputeRGBStride(format, GetSize().width);
    170 }
    171 
    172 bool WebRenderTextureHost::NeedsDeferredDeletion() const {
    173  return mWrappedTextureHost->NeedsDeferredDeletion();
    174 }
    175 
    176 uint32_t WebRenderTextureHost::NumSubTextures() {
    177  return mWrappedTextureHost->NumSubTextures();
    178 }
    179 
    180 void WebRenderTextureHost::PushResourceUpdates(
    181    wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
    182    const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) {
    183  MOZ_ASSERT(GetExternalImageKey() == aExtID);
    184 
    185  mWrappedTextureHost->PushResourceUpdates(aResources, aOp, aImageKeys, aExtID);
    186 }
    187 
    188 void WebRenderTextureHost::PushDisplayItems(
    189    wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
    190    const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
    191    const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) {
    192  MOZ_ASSERT(aImageKeys.length() > 0);
    193 
    194  mWrappedTextureHost->PushDisplayItems(aBuilder, aBounds, aClip, aFilter,
    195                                        aImageKeys, aFlags);
    196 }
    197 
    198 bool WebRenderTextureHost::SupportsExternalCompositing(
    199    WebRenderBackend aBackend) {
    200  return mWrappedTextureHost->SupportsExternalCompositing(aBackend);
    201 }
    202 
    203 void WebRenderTextureHost::SetReadFence(Fence* aReadFence) {
    204  return mWrappedTextureHost->SetReadFence(aReadFence);
    205 }
    206 
    207 AndroidHardwareBuffer* WebRenderTextureHost::GetAndroidHardwareBuffer() const {
    208  return mWrappedTextureHost->GetAndroidHardwareBuffer();
    209 }
    210 
    211 TextureHostType WebRenderTextureHost::GetTextureHostType() {
    212  return mWrappedTextureHost->GetTextureHostType();
    213 }
    214 
    215 }  // namespace mozilla::layers