tor-browser

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

RenderMacIOSurfaceTextureHost.cpp (6407B)


      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 "RenderMacIOSurfaceTextureHost.h"
      8 
      9 #ifdef XP_MACOSX
     10 #  include "GLContextCGL.h"
     11 #else
     12 #  include "GLContextEAGL.h"
     13 #endif
     14 
     15 #include "mozilla/gfx/Logging.h"
     16 #include "mozilla/layers/GpuFence.h"
     17 #include "mozilla/ProfilerLabels.h"
     18 #include "mozilla/ProfilerMarkers.h"
     19 #include "mozilla/TimeStamp.h"
     20 #include "ScopedGLHelpers.h"
     21 
     22 namespace mozilla {
     23 namespace wr {
     24 
     25 static bool CreateTextureForPlane(uint8_t aPlaneID, gl::GLContext* aGL,
     26                                  MacIOSurface* aSurface, GLuint* aTexture) {
     27  MOZ_ASSERT(aGL && aSurface && aTexture);
     28 
     29  aGL->fGenTextures(1, aTexture);
     30  ActivateBindAndTexParameteri(aGL, LOCAL_GL_TEXTURE0,
     31                               LOCAL_GL_TEXTURE_RECTANGLE_ARB, *aTexture);
     32  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T,
     33                      LOCAL_GL_CLAMP_TO_EDGE);
     34  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S,
     35                      LOCAL_GL_CLAMP_TO_EDGE);
     36 
     37  gfx::SurfaceFormat readFormat = gfx::SurfaceFormat::UNKNOWN;
     38  bool result = aSurface->BindTexImage(aGL, aPlaneID, &readFormat);
     39  // If this is a yuv format, the Webrender only supports YUY2 interleaving
     40  // format.
     41  MOZ_ASSERT(aSurface->GetFormat() != gfx::SurfaceFormat::YUY2 ||
     42             readFormat == gfx::SurfaceFormat::YUY2);
     43 
     44  return result;
     45 }
     46 
     47 RenderMacIOSurfaceTextureHost::RenderMacIOSurfaceTextureHost(
     48    MacIOSurface* aSurface, layers::GpuFence* aGpuFence)
     49    : mSurface(aSurface), mGpuFence(aGpuFence), mTextureHandles{0, 0, 0} {
     50  MOZ_COUNT_CTOR_INHERITED(RenderMacIOSurfaceTextureHost, RenderTextureHost);
     51 }
     52 
     53 RenderMacIOSurfaceTextureHost::~RenderMacIOSurfaceTextureHost() {
     54  MOZ_COUNT_DTOR_INHERITED(RenderMacIOSurfaceTextureHost, RenderTextureHost);
     55  DeleteTextureHandle();
     56 }
     57 
     58 GLuint RenderMacIOSurfaceTextureHost::GetGLHandle(uint8_t aChannelIndex) const {
     59  MOZ_ASSERT(mSurface);
     60  MOZ_ASSERT((mSurface->GetPlaneCount() == 0)
     61                 ? (aChannelIndex == mSurface->GetPlaneCount())
     62                 : (aChannelIndex < mSurface->GetPlaneCount()));
     63  return mTextureHandles[aChannelIndex];
     64 }
     65 
     66 gfx::IntSize RenderMacIOSurfaceTextureHost::GetSize(
     67    uint8_t aChannelIndex) const {
     68  MOZ_ASSERT(mSurface);
     69  MOZ_ASSERT((mSurface->GetPlaneCount() == 0)
     70                 ? (aChannelIndex == mSurface->GetPlaneCount())
     71                 : (aChannelIndex < mSurface->GetPlaneCount()));
     72 
     73  if (!mSurface) {
     74    return gfx::IntSize();
     75  }
     76  return gfx::IntSize(mSurface->GetDevicePixelWidth(aChannelIndex),
     77                      mSurface->GetDevicePixelHeight(aChannelIndex));
     78 }
     79 
     80 size_t RenderMacIOSurfaceTextureHost::Bytes() {
     81  return mSurface->GetAllocSize();
     82 }
     83 
     84 wr::WrExternalImage RenderMacIOSurfaceTextureHost::Lock(uint8_t aChannelIndex,
     85                                                        gl::GLContext* aGL) {
     86  if (mGL.get() != aGL) {
     87    // release the texture handle in the previous gl context
     88    DeleteTextureHandle();
     89    mGL = aGL;
     90    mGL->MakeCurrent();
     91  }
     92 
     93  if (!mSurface || !mGL || !mGL->MakeCurrent()) {
     94    return InvalidToWrExternalImage();
     95  }
     96 
     97  if (!mTextureHandles[0]) {
     98 #ifdef XP_MACOSX
     99    MOZ_ASSERT(gl::GLContextCGL::Cast(mGL.get())->GetCGLContext());
    100 #else
    101    MOZ_ASSERT(gl::GLContextEAGL::Cast(mGL.get())->GetEAGLContext());
    102 #endif
    103 
    104    // The result of GetPlaneCount() is 0 for single plane format, but it will
    105    // be 2 if the format has 2 planar data.
    106    CreateTextureForPlane(0, mGL, mSurface, &(mTextureHandles[0]));
    107    for (size_t i = 1; i < mSurface->GetPlaneCount(); ++i) {
    108      CreateTextureForPlane(i, mGL, mSurface, &(mTextureHandles[i]));
    109    }
    110  }
    111 
    112  if (mGpuFence) {
    113    // This timeout matches the acquisition timeout for the keyed mutex
    114    // in the D3D11 texture host.
    115    auto timeout = TimeDuration::FromMilliseconds(10000);
    116    auto start = TimeStamp::Now();
    117    AUTO_PROFILER_MARKER("Lock MacIOSurfaceTexture", GRAPHICS);
    118    while (!mGpuFence->HasCompleted() && (TimeStamp::Now() - start) < timeout) {
    119      PR_Sleep(PR_MillisecondsToInterval(1));
    120    }
    121  } else {
    122    PROFILER_MARKER_UNTYPED("No GpuFence", GRAPHICS);
    123  }
    124 
    125  const auto size = GetSize(aChannelIndex);
    126  return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0.0, 0.0,
    127                                        static_cast<float>(size.width),
    128                                        static_cast<float>(size.height));
    129 }
    130 
    131 void RenderMacIOSurfaceTextureHost::Unlock() {}
    132 
    133 void RenderMacIOSurfaceTextureHost::DeleteTextureHandle() {
    134  if (mTextureHandles[0] != 0 && mGL && mGL->MakeCurrent()) {
    135    // Calling glDeleteTextures on 0 isn't an error. So, just make them a single
    136    // call.
    137    mGL->fDeleteTextures(3, mTextureHandles);
    138    for (size_t i = 0; i < 3; ++i) {
    139      mTextureHandles[i] = 0;
    140    }
    141  }
    142 }
    143 
    144 size_t RenderMacIOSurfaceTextureHost::GetPlaneCount() const {
    145  size_t planeCount = mSurface->GetPlaneCount();
    146  return planeCount > 0 ? planeCount : 1;
    147 }
    148 
    149 gfx::SurfaceFormat RenderMacIOSurfaceTextureHost::GetFormat() const {
    150  return mSurface->GetFormat();
    151 }
    152 
    153 gfx::ColorDepth RenderMacIOSurfaceTextureHost::GetColorDepth() const {
    154  return mSurface->GetColorDepth();
    155 }
    156 
    157 gfx::YUVRangedColorSpace RenderMacIOSurfaceTextureHost::GetYUVColorSpace()
    158    const {
    159  return ToYUVRangedColorSpace(mSurface->GetYUVColorSpace(),
    160                               mSurface->GetColorRange());
    161 }
    162 
    163 bool RenderMacIOSurfaceTextureHost::MapPlane(RenderCompositor* aCompositor,
    164                                             uint8_t aChannelIndex,
    165                                             PlaneInfo& aPlaneInfo) {
    166  if (!aChannelIndex) {
    167    if (NS_WARN_IF(!mSurface->Lock())) {
    168      return false;
    169    }
    170  }
    171  aPlaneInfo.mData = mSurface->GetBaseAddressOfPlane(aChannelIndex);
    172  aPlaneInfo.mStride = mSurface->GetBytesPerRow(aChannelIndex);
    173  aPlaneInfo.mSize =
    174      gfx::IntSize(mSurface->GetDevicePixelWidth(aChannelIndex),
    175                   mSurface->GetDevicePixelHeight(aChannelIndex));
    176  return true;
    177 }
    178 
    179 void RenderMacIOSurfaceTextureHost::UnmapPlanes() { mSurface->Unlock(); }
    180 
    181 }  // namespace wr
    182 }  // namespace mozilla