tor-browser

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

RenderExternalTextureHost.cpp (7841B)


      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 "RenderExternalTextureHost.h"
      8 
      9 #include "mozilla/gfx/Logging.h"
     10 #include "mozilla/layers/ImageDataSerializer.h"
     11 
     12 #include "GLContext.h"
     13 
     14 namespace mozilla {
     15 namespace wr {
     16 
     17 RenderExternalTextureHost::RenderExternalTextureHost(
     18    uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor)
     19    : mBuffer(aBuffer),
     20      mDescriptor(aDescriptor),
     21      mInitialized(false),
     22      mTextureUpdateNeeded(true) {
     23  MOZ_COUNT_CTOR_INHERITED(RenderExternalTextureHost, RenderTextureHost);
     24 
     25  switch (mDescriptor.type()) {
     26    case layers::BufferDescriptor::TYCbCrDescriptor: {
     27      const layers::YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
     28      mSize = ycbcr.display().Size();
     29      mFormat = gfx::SurfaceFormat::YUV420;
     30      break;
     31    }
     32    case layers::BufferDescriptor::TRGBDescriptor: {
     33      const layers::RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
     34      mSize = rgb.size();
     35      mFormat = rgb.format();
     36      break;
     37    }
     38    default:
     39      gfxCriticalError() << "Bad buffer host descriptor "
     40                         << (int)mDescriptor.type();
     41      MOZ_CRASH("GFX: Bad descriptor");
     42  }
     43 }
     44 
     45 RenderExternalTextureHost::~RenderExternalTextureHost() {
     46  MOZ_COUNT_DTOR_INHERITED(RenderExternalTextureHost, RenderTextureHost);
     47 
     48  if (NS_WARN_IF(!IsReadyForDeletion())) {
     49    gfxCriticalNote << "RenderExternalTextureHost sync failed";
     50  }
     51 
     52  DeleteTextures();
     53 }
     54 
     55 bool RenderExternalTextureHost::CreateSurfaces() {
     56  if (!IsYUV()) {
     57    mSurfaces[0] = gfx::Factory::CreateWrappingDataSourceSurface(
     58        GetBuffer(),
     59        layers::ImageDataSerializer::GetRGBStride(
     60            mDescriptor.get_RGBDescriptor()),
     61        mSize, mFormat);
     62  } else {
     63    const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
     64    const gfx::SurfaceFormat surfaceFormat =
     65        SurfaceFormatForColorDepth(desc.colorDepth());
     66    auto cbcrSize = layers::ImageDataSerializer::GetCroppedCbCrSize(desc);
     67 
     68    mSurfaces[0] = gfx::Factory::CreateWrappingDataSourceSurface(
     69        layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc),
     70        desc.yStride(), desc.display().Size(), surfaceFormat);
     71    mSurfaces[1] = gfx::Factory::CreateWrappingDataSourceSurface(
     72        layers::ImageDataSerializer::GetCbChannel(GetBuffer(), desc),
     73        desc.cbCrStride(), cbcrSize, surfaceFormat);
     74    mSurfaces[2] = gfx::Factory::CreateWrappingDataSourceSurface(
     75        layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc),
     76        desc.cbCrStride(), cbcrSize, surfaceFormat);
     77  }
     78 
     79  for (size_t i = 0; i < PlaneCount(); ++i) {
     80    if (NS_WARN_IF(!mSurfaces[i])) {
     81      gfxCriticalNote << "Surface is null";
     82      return false;
     83    }
     84  }
     85 
     86  return true;
     87 }
     88 
     89 void RenderExternalTextureHost::DeleteSurfaces() {
     90  for (size_t i = 0; i < PlaneCount(); ++i) {
     91    mSurfaces[i] = nullptr;
     92  }
     93 }
     94 
     95 void RenderExternalTextureHost::DeleteTextures() {
     96  for (size_t i = 0; i < PlaneCount(); ++i) {
     97    mTextureSources[i] = nullptr;
     98    mImages[i] = InvalidToWrExternalImage();
     99  }
    100 }
    101 
    102 bool RenderExternalTextureHost::InitializeIfNeeded() {
    103  if (mInitialized) {
    104    return true;
    105  }
    106 
    107  if (!GetBuffer()) {
    108    // We hit some problems to get the shmem.
    109    gfxCriticalNote << "GetBuffer Failed";
    110    return false;
    111  }
    112 
    113  if (!CreateSurfaces()) {
    114    DeleteSurfaces();
    115    return false;
    116  }
    117 
    118  mInitialized = true;
    119  return mInitialized;
    120 }
    121 
    122 bool RenderExternalTextureHost::IsReadyForDeletion() {
    123  if (!mInitialized) {
    124    return true;
    125  }
    126 
    127  auto& textureSource = mTextureSources[0];
    128  if (textureSource) {
    129    return textureSource->Sync(false);
    130  }
    131 
    132  return true;
    133 }
    134 
    135 wr::WrExternalImage RenderExternalTextureHost::Lock(uint8_t aChannelIndex,
    136                                                    gl::GLContext* aGL) {
    137  if (mGL.get() != aGL) {
    138    mGL = aGL;
    139    mGL->MakeCurrent();
    140  }
    141 
    142  if (!mGL || !mGL->MakeCurrent()) {
    143    return InvalidToWrExternalImage();
    144  }
    145 
    146  if (!InitializeIfNeeded()) {
    147    return InvalidToWrExternalImage();
    148  }
    149 
    150  UpdateTextures();
    151  return mImages[aChannelIndex];
    152 }
    153 
    154 void RenderExternalTextureHost::PrepareForUse() { mTextureUpdateNeeded = true; }
    155 
    156 void RenderExternalTextureHost::Unlock() {}
    157 
    158 void RenderExternalTextureHost::UpdateTexture(size_t aIndex) {
    159  MOZ_ASSERT(mSurfaces[aIndex]);
    160 
    161  auto& texture = mTextureSources[aIndex];
    162 
    163  if (texture) {
    164    texture->Update(mSurfaces[aIndex]);
    165  } else {
    166    texture = new layers::DirectMapTextureSource(mGL, mSurfaces[aIndex]);
    167 
    168    const GLuint handle = texture->GetTextureHandle();
    169    const gfx::IntSize size = texture->GetSize();
    170    mImages[aIndex] = NativeTextureToWrExternalImage(
    171        handle, 0.0, 0.0, static_cast<float>(size.width),
    172        static_cast<float>(size.height));
    173  }
    174 
    175  MOZ_ASSERT(mGL->GetError() == LOCAL_GL_NO_ERROR);
    176 }
    177 
    178 void RenderExternalTextureHost::UpdateTextures() {
    179  if (!mTextureUpdateNeeded) {
    180    // Nothing to do here.
    181    return;
    182  }
    183 
    184  for (size_t i = 0; i < PlaneCount(); ++i) {
    185    UpdateTexture(i);
    186  }
    187 
    188  mTextureSources[0]->MaybeFenceTexture();
    189  mTextureUpdateNeeded = false;
    190 }
    191 
    192 size_t RenderExternalTextureHost::GetPlaneCount() const { return PlaneCount(); }
    193 
    194 gfx::SurfaceFormat RenderExternalTextureHost::GetFormat() const {
    195  return mFormat;
    196 }
    197 
    198 gfx::ColorDepth RenderExternalTextureHost::GetColorDepth() const {
    199  switch (mDescriptor.type()) {
    200    case layers::BufferDescriptor::TYCbCrDescriptor:
    201      return mDescriptor.get_YCbCrDescriptor().colorDepth();
    202    default:
    203      return gfx::ColorDepth::COLOR_8;
    204  }
    205 }
    206 
    207 gfx::YUVRangedColorSpace RenderExternalTextureHost::GetYUVColorSpace() const {
    208  switch (mDescriptor.type()) {
    209    case layers::BufferDescriptor::TYCbCrDescriptor:
    210      return gfx::GetYUVRangedColorSpace(mDescriptor.get_YCbCrDescriptor());
    211    default:
    212      return gfx::YUVRangedColorSpace::Default;
    213  }
    214 }
    215 
    216 bool RenderExternalTextureHost::MapPlane(RenderCompositor* aCompositor,
    217                                         uint8_t aChannelIndex,
    218                                         PlaneInfo& aPlaneInfo) {
    219  if (!mBuffer) {
    220    // We hit some problems to get the shmem.
    221    gfxCriticalNote << "GetBuffer Failed";
    222    return false;
    223  }
    224 
    225  switch (mDescriptor.type()) {
    226    case layers::BufferDescriptor::TYCbCrDescriptor: {
    227      const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
    228      switch (aChannelIndex) {
    229        case 0:
    230          aPlaneInfo.mData =
    231              layers::ImageDataSerializer::GetYChannel(mBuffer, desc);
    232          aPlaneInfo.mStride = desc.yStride();
    233          aPlaneInfo.mSize = desc.display().Size();
    234          break;
    235        case 1:
    236          aPlaneInfo.mData =
    237              layers::ImageDataSerializer::GetCbChannel(mBuffer, desc);
    238          aPlaneInfo.mStride = desc.cbCrStride();
    239          aPlaneInfo.mSize =
    240              layers::ImageDataSerializer::GetCroppedCbCrSize(desc);
    241          break;
    242        case 2:
    243          aPlaneInfo.mData =
    244              layers::ImageDataSerializer::GetCrChannel(mBuffer, desc);
    245          aPlaneInfo.mStride = desc.cbCrStride();
    246          aPlaneInfo.mSize =
    247              layers::ImageDataSerializer::GetCroppedCbCrSize(desc);
    248          break;
    249      }
    250      break;
    251    }
    252    default: {
    253      const layers::RGBDescriptor& desc = mDescriptor.get_RGBDescriptor();
    254      aPlaneInfo.mData = mBuffer;
    255      aPlaneInfo.mStride = layers::ImageDataSerializer::GetRGBStride(desc);
    256      aPlaneInfo.mSize = desc.size();
    257      break;
    258    }
    259  }
    260  return true;
    261 }
    262 
    263 void RenderExternalTextureHost::UnmapPlanes() {}
    264 
    265 }  // namespace wr
    266 }  // namespace mozilla