tor-browser

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

RenderTextureHostSWGL.cpp (7461B)


      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 "RenderTextureHostSWGL.h"
      8 
      9 #include "mozilla/gfx/Logging.h"
     10 #include "mozilla/layers/TextureHost.h"
     11 #include "RenderThread.h"
     12 
     13 namespace mozilla {
     14 namespace wr {
     15 
     16 bool RenderTextureHostSWGL::UpdatePlanes(RenderCompositor* aCompositor) {
     17  wr_swgl_make_current(mContext);
     18  size_t planeCount = GetPlaneCount();
     19  bool texInit = false;
     20  if (mPlanes.size() < planeCount) {
     21    mPlanes.reserve(planeCount);
     22    while (mPlanes.size() < planeCount) {
     23      mPlanes.push_back(PlaneInfo(wr_swgl_gen_texture(mContext)));
     24    }
     25    texInit = true;
     26  }
     27  gfx::SurfaceFormat format = GetFormat();
     28  gfx::ColorDepth colorDepth = GetColorDepth();
     29  for (size_t i = 0; i < planeCount; i++) {
     30    PlaneInfo& plane = mPlanes[i];
     31    if (!MapPlane(aCompositor, i, plane)) {
     32      if (i > 0) {
     33        UnmapPlanes();
     34      }
     35      return false;
     36    }
     37    GLenum internalFormat = 0;
     38    switch (format) {
     39      case gfx::SurfaceFormat::B8G8R8A8:
     40      case gfx::SurfaceFormat::B8G8R8X8:
     41        MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_8);
     42        internalFormat = LOCAL_GL_RGBA8;
     43        break;
     44      case gfx::SurfaceFormat::YUV420:
     45        switch (colorDepth) {
     46          case gfx::ColorDepth::COLOR_8:
     47            internalFormat = LOCAL_GL_R8;
     48            break;
     49          case gfx::ColorDepth::COLOR_10:
     50          case gfx::ColorDepth::COLOR_12:
     51          case gfx::ColorDepth::COLOR_16:
     52            internalFormat = LOCAL_GL_R16;
     53            break;
     54        }
     55        break;
     56      case gfx::SurfaceFormat::NV12:
     57        switch (colorDepth) {
     58          case gfx::ColorDepth::COLOR_8:
     59            internalFormat = i > 0 ? LOCAL_GL_RG8 : LOCAL_GL_R8;
     60            break;
     61          case gfx::ColorDepth::COLOR_10:
     62          case gfx::ColorDepth::COLOR_12:
     63          case gfx::ColorDepth::COLOR_16:
     64            internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16;
     65            break;
     66        }
     67        break;
     68      case gfx::SurfaceFormat::P010:
     69        MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_10);
     70        internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16;
     71        break;
     72      case gfx::SurfaceFormat::P016:
     73        MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_16);
     74        internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16;
     75        break;
     76      case gfx::SurfaceFormat::YUY2:
     77        MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_8);
     78        internalFormat = LOCAL_GL_RGB_RAW_422_APPLE;
     79        break;
     80      default:
     81        MOZ_RELEASE_ASSERT(false, "Unhandled external image format");
     82        break;
     83    }
     84    wr_swgl_set_texture_buffer(mContext, plane.mTexture, internalFormat,
     85                               plane.mSize.width, plane.mSize.height,
     86                               plane.mStride, plane.mData, 0, 0);
     87  }
     88  if (texInit) {
     89    // Initialize the mip filters to linear by default.
     90    for (const auto& plane : mPlanes) {
     91      wr_swgl_set_texture_parameter(mContext, plane.mTexture,
     92                                    LOCAL_GL_TEXTURE_MIN_FILTER,
     93                                    LOCAL_GL_LINEAR);
     94      wr_swgl_set_texture_parameter(mContext, plane.mTexture,
     95                                    LOCAL_GL_TEXTURE_MAG_FILTER,
     96                                    LOCAL_GL_LINEAR);
     97    }
     98  }
     99  return true;
    100 }
    101 
    102 bool RenderTextureHostSWGL::SetContext(void* aContext) {
    103  if (mContext != aContext) {
    104    CleanupPlanes();
    105    mContext = aContext;
    106    wr_swgl_reference_context(mContext);
    107  }
    108  return mContext != nullptr;
    109 }
    110 
    111 wr::WrExternalImage RenderTextureHostSWGL::LockSWGL(
    112    uint8_t aChannelIndex, void* aContext, RenderCompositor* aCompositor) {
    113  if (!SetContext(aContext)) {
    114    return InvalidToWrExternalImage();
    115  }
    116  if (!mLocked) {
    117    if (!UpdatePlanes(aCompositor)) {
    118      return InvalidToWrExternalImage();
    119    }
    120    mLocked = true;
    121  }
    122  if (aChannelIndex >= mPlanes.size()) {
    123    return InvalidToWrExternalImage();
    124  }
    125  const PlaneInfo& plane = mPlanes[aChannelIndex];
    126 
    127  // Prefer native textures, unless our backend forbids it.
    128  layers::TextureHost::NativeTexturePolicy policy =
    129      layers::TextureHost::BackendNativeTexturePolicy(
    130          layers::WebRenderBackend::SOFTWARE, plane.mSize);
    131  return policy == layers::TextureHost::NativeTexturePolicy::FORBID
    132             ? RawDataToWrExternalImage((uint8_t*)plane.mData,
    133                                        plane.mStride * plane.mSize.height)
    134             : NativeTextureToWrExternalImage(
    135                   plane.mTexture, 0.0, 0.0,
    136                   static_cast<float>(plane.mSize.width),
    137                   static_cast<float>(plane.mSize.height));
    138 }
    139 
    140 void RenderTextureHostSWGL::UnlockSWGL() {
    141  if (mLocked) {
    142    mLocked = false;
    143    UnmapPlanes();
    144  }
    145 }
    146 
    147 void RenderTextureHostSWGL::CleanupPlanes() {
    148  if (!mContext) {
    149    return;
    150  }
    151  if (!mPlanes.empty()) {
    152    wr_swgl_make_current(mContext);
    153    for (const auto& plane : mPlanes) {
    154      wr_swgl_delete_texture(mContext, plane.mTexture);
    155    }
    156    mPlanes.clear();
    157  }
    158  wr_swgl_destroy_context(mContext);
    159  mContext = nullptr;
    160 }
    161 
    162 RenderTextureHostSWGL::~RenderTextureHostSWGL() { CleanupPlanes(); }
    163 
    164 bool RenderTextureHostSWGL::LockSWGLCompositeSurface(
    165    void* aContext, wr::SWGLCompositeSurfaceInfo* aInfo) {
    166  if (!SetContext(aContext)) {
    167    return false;
    168  }
    169  if (!mLocked) {
    170    if (!UpdatePlanes(nullptr)) {
    171      return false;
    172    }
    173    mLocked = true;
    174  }
    175  MOZ_ASSERT(mPlanes.size() <= 3);
    176  for (size_t i = 0; i < mPlanes.size(); i++) {
    177    aInfo->textures[i] = mPlanes[i].mTexture;
    178  }
    179  switch (GetFormat()) {
    180    case gfx::SurfaceFormat::YUV420:
    181    case gfx::SurfaceFormat::NV12:
    182    case gfx::SurfaceFormat::P010:
    183    case gfx::SurfaceFormat::P016:
    184    case gfx::SurfaceFormat::YUY2: {
    185      aInfo->yuv_planes = mPlanes.size();
    186      auto colorSpace = GetYUVColorSpace();
    187      aInfo->color_space = ToWrYuvRangedColorSpace(colorSpace);
    188      auto colorDepth = GetColorDepth();
    189      aInfo->color_depth = ToWrColorDepth(colorDepth);
    190      break;
    191    }
    192    case gfx::SurfaceFormat::B8G8R8A8:
    193    case gfx::SurfaceFormat::B8G8R8X8:
    194      break;
    195    default:
    196      gfxCriticalNote << "Unhandled external image format: " << GetFormat();
    197      MOZ_RELEASE_ASSERT(false, "Unhandled external image format");
    198      break;
    199  }
    200  aInfo->size.width = mPlanes[0].mSize.width;
    201  aInfo->size.height = mPlanes[0].mSize.height;
    202  return true;
    203 }
    204 
    205 bool wr_swgl_lock_composite_surface(void* aContext, wr::ExternalImageId aId,
    206                                    wr::SWGLCompositeSurfaceInfo* aInfo) {
    207  RenderTextureHost* texture = RenderThread::Get()->GetRenderTexture(aId);
    208  if (!texture) {
    209    return false;
    210  }
    211  RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL();
    212  if (!swglTex) {
    213    return false;
    214  }
    215  return swglTex->LockSWGLCompositeSurface(aContext, aInfo);
    216 }
    217 
    218 void wr_swgl_unlock_composite_surface(void* aContext, wr::ExternalImageId aId) {
    219  RenderTextureHost* texture = RenderThread::Get()->GetRenderTexture(aId);
    220  if (!texture) {
    221    return;
    222  }
    223  RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL();
    224  if (!swglTex) {
    225    return;
    226  }
    227  swglTex->UnlockSWGL();
    228 }
    229 
    230 }  // namespace wr
    231 }  // namespace mozilla