tor-browser

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

DcompSurfaceImage.cpp (6487B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "DcompSurfaceImage.h"
      7 
      8 #include "mozilla/ipc/FileDescriptor.h"
      9 #include "mozilla/gfx/gfxVars.h"
     10 #include "mozilla/layers/CompositorTypes.h"
     11 #include "mozilla/layers/LayersSurfaces.h"
     12 #include "mozilla/layers/TextureForwarder.h"
     13 #include "mozilla/layers/KnowsCompositor.h"
     14 #include "mozilla/webrender/RenderDcompSurfaceTextureHost.h"
     15 #include "mozilla/webrender/WebRenderAPI.h"
     16 
     17 extern mozilla::LazyLogModule gDcompSurface;
     18 #define LOG(...) MOZ_LOG(gDcompSurface, LogLevel::Debug, (__VA_ARGS__))
     19 
     20 namespace mozilla::layers {
     21 
     22 already_AddRefed<TextureHost> CreateTextureHostDcompSurface(
     23    const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator,
     24    LayersBackend aBackend, TextureFlags aFlags) {
     25  MOZ_ASSERT(aDesc.type() == SurfaceDescriptor::TSurfaceDescriptorDcompSurface);
     26  RefPtr<TextureHost> result = new DcompSurfaceHandleHost(
     27      aFlags, aDesc.get_SurfaceDescriptorDcompSurface());
     28  return result.forget();
     29 }
     30 
     31 /* static */
     32 already_AddRefed<TextureClient> DcompSurfaceTexture::CreateTextureClient(
     33    HANDLE aHandle, gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
     34    KnowsCompositor* aKnowsCompositor) {
     35  RefPtr<TextureClient> textureClient = MakeAndAddRef<TextureClient>(
     36      new DcompSurfaceTexture(aHandle, aSize, aFormat), TextureFlags::NO_FLAGS,
     37      aKnowsCompositor->GetTextureForwarder());
     38  return textureClient.forget();
     39 }
     40 
     41 DcompSurfaceTexture::~DcompSurfaceTexture() {
     42  LOG("Destroy DcompSurfaceTexture %p, close handle=%p", this, mHandle);
     43  CloseHandle(mHandle);
     44 }
     45 
     46 bool DcompSurfaceTexture::Serialize(SurfaceDescriptor& aOutDescriptor) {
     47  aOutDescriptor = SurfaceDescriptorDcompSurface(ipc::FileDescriptor(mHandle),
     48                                                 mSize, mFormat);
     49  return true;
     50 }
     51 
     52 void DcompSurfaceTexture::GetSubDescriptor(
     53    RemoteDecoderVideoSubDescriptor* aOutDesc) {
     54  *aOutDesc = SurfaceDescriptorDcompSurface(ipc::FileDescriptor(mHandle), mSize,
     55                                            mFormat);
     56 }
     57 
     58 DcompSurfaceImage::DcompSurfaceImage(HANDLE aHandle, gfx::IntSize aSize,
     59                                     gfx::SurfaceFormat aFormat,
     60                                     KnowsCompositor* aKnowsCompositor)
     61    : Image(nullptr, ImageFormat::DCOMP_SURFACE),
     62      mTextureClient(DcompSurfaceTexture::CreateTextureClient(
     63          aHandle, aSize, aFormat, aKnowsCompositor)) {
     64  // Dcomp surface supports DXGI_FORMAT_B8G8R8A8_UNORM,
     65  // DXGI_FORMAT_R8G8B8A8_UNORM and DXGI_FORMAT_R16G16B16A16_FLOAT
     66  MOZ_ASSERT(aFormat == gfx::SurfaceFormat::B8G8R8A8 ||
     67             aFormat == gfx::SurfaceFormat::R8G8B8A8 ||
     68             aFormat == gfx::SurfaceFormat::R16G16B16A16F);
     69 }
     70 
     71 TextureClient* DcompSurfaceImage::GetTextureClient(
     72    KnowsCompositor* aKnowsCompositor) {
     73  return mTextureClient;
     74 }
     75 
     76 DcompSurfaceHandleHost::DcompSurfaceHandleHost(
     77    TextureFlags aFlags, const SurfaceDescriptorDcompSurface& aDescriptor)
     78    : TextureHost(TextureHostType::DcompSurface, aFlags),
     79      mHandle(const_cast<ipc::FileDescriptor&>(aDescriptor.handle())
     80                  .TakePlatformHandle()),
     81      mSize(aDescriptor.size()),
     82      mFormat(aDescriptor.format()) {
     83  LOG("Create DcompSurfaceHandleHost %p", this);
     84 }
     85 
     86 DcompSurfaceHandleHost::~DcompSurfaceHandleHost() {
     87  LOG("Destroy DcompSurfaceHandleHost %p", this);
     88 }
     89 
     90 void DcompSurfaceHandleHost::CreateRenderTexture(
     91    const wr::ExternalImageId& aExternalImageId) {
     92  MOZ_ASSERT(mExternalImageId.isSome());
     93  LOG("DcompSurfaceHandleHost %p CreateRenderTexture, ext-id=%" PRIu64, this,
     94      wr::AsUint64(aExternalImageId));
     95  RefPtr<wr::RenderTextureHost> texture =
     96      new wr::RenderDcompSurfaceTextureHost(mHandle.get(), mSize, mFormat);
     97  wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId,
     98                                                 texture.forget());
     99 }
    100 
    101 void DcompSurfaceHandleHost::PushResourceUpdates(
    102    wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
    103    const Range<wr::ImageKey>& aImageKeys,
    104    const wr::ExternalImageId& aExternalImageId) {
    105  if (!gfx::gfxVars::UseWebRenderANGLE()) {
    106    MOZ_ASSERT_UNREACHABLE("Unexpected to be called without ANGLE");
    107    return;
    108  }
    109  MOZ_ASSERT(mHandle);
    110  MOZ_ASSERT(aImageKeys.length() == 1);
    111  auto method = aOp == TextureHost::ADD_IMAGE
    112                    ? &wr::TransactionBuilder::AddExternalImage
    113                    : &wr::TransactionBuilder::UpdateExternalImage;
    114  wr::ImageDescriptor descriptor(mSize, GetFormat());
    115  // Prefer TextureExternal unless the backend requires TextureRect.
    116  TextureHost::NativeTexturePolicy policy =
    117      TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
    118                                              mSize);
    119  auto imageType = policy == TextureHost::NativeTexturePolicy::REQUIRE
    120                       ? wr::ExternalImageType::TextureHandle(
    121                             wr::ImageBufferKind::TextureRect)
    122                       : wr::ExternalImageType::TextureHandle(
    123                             wr::ImageBufferKind::TextureExternal);
    124  LOG("DcompSurfaceHandleHost %p PushResourceUpdate, exi-id=%" PRIu64
    125      ", type=%s",
    126      this, wr::AsUint64(aExternalImageId),
    127      policy == TextureHost::NativeTexturePolicy::REQUIRE ? "rect" : "ext");
    128  (aResources.*method)(aImageKeys[0], descriptor, aExternalImageId, imageType,
    129                       0, /* aNormalizedUvs */ false);
    130 }
    131 
    132 void DcompSurfaceHandleHost::PushDisplayItems(
    133    wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
    134    const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
    135    const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) {
    136  if (!gfx::gfxVars::UseWebRenderANGLE()) {
    137    MOZ_ASSERT_UNREACHABLE("Unexpected to be called without ANGLE");
    138    return;
    139  }
    140  LOG("DcompSurfaceHandleHost %p PushDisplayItems", this);
    141  MOZ_ASSERT(aImageKeys.length() == 1);
    142  aBuilder.PushImage(
    143      aBounds, aClip, true, false, aFilter, aImageKeys[0],
    144      !(mFlags & TextureFlags::NON_PREMULTIPLIED),
    145      wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
    146      aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE),
    147      SupportsExternalCompositing(aBuilder.GetBackendType()));
    148 }
    149 
    150 }  // namespace mozilla::layers
    151 
    152 #undef LOG