tor-browser

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

TextureHostOGL.cpp (38777B)


      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 "TextureHostOGL.h"
      8 
      9 #include "GLContextEGL.h"  // for GLContext, etc
     10 #include "GLLibraryEGL.h"  // for GLLibraryEGL
     11 #include "GLUploadHelpers.h"
     12 #include "GLReadTexImageHelper.h"
     13 #include "gfx2DGlue.h"             // for ContentForFormat, etc
     14 #include "mozilla/gfx/2D.h"        // for DataSourceSurface
     15 #include "mozilla/gfx/BaseSize.h"  // for BaseSize
     16 #include "mozilla/gfx/gfxVars.h"
     17 #include "mozilla/gfx/Logging.h"  // for gfxCriticalError
     18 #include "mozilla/layers/Fence.h"
     19 #include "mozilla/layers/ISurfaceAllocator.h"
     20 #include "mozilla/webrender/RenderEGLImageTextureHost.h"
     21 #include "mozilla/webrender/WebRenderAPI.h"
     22 #include "nsRegion.h"             // for nsIntRegion
     23 #include "GfxTexturesReporter.h"  // for GfxTexturesReporter
     24 #include "GeckoProfiler.h"
     25 
     26 #ifdef XP_MACOSX
     27 #  include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
     28 #endif
     29 
     30 #ifdef MOZ_WIDGET_ANDROID
     31 #  include "mozilla/layers/AndroidHardwareBuffer.h"
     32 #  include "mozilla/webrender/RenderAndroidHardwareBufferTextureHost.h"
     33 #  include "mozilla/webrender/RenderAndroidSurfaceTextureHost.h"
     34 #endif
     35 
     36 #ifdef MOZ_WIDGET_GTK
     37 #  include "mozilla/layers/DMABUFTextureHostOGL.h"
     38 #endif
     39 
     40 using namespace mozilla::gl;
     41 using namespace mozilla::gfx;
     42 
     43 namespace mozilla {
     44 namespace layers {
     45 
     46 class Compositor;
     47 
     48 void ApplySamplingFilterToBoundTexture(gl::GLContext* aGL,
     49                                       gfx::SamplingFilter aSamplingFilter,
     50                                       GLuint aTarget) {
     51  GLenum filter =
     52      (aSamplingFilter == gfx::SamplingFilter::POINT ? LOCAL_GL_NEAREST
     53                                                     : LOCAL_GL_LINEAR);
     54 
     55  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, filter);
     56  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, filter);
     57 }
     58 
     59 already_AddRefed<TextureHost> CreateTextureHostOGL(
     60    const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator,
     61    LayersBackend aBackend, TextureFlags aFlags) {
     62  RefPtr<TextureHost> result;
     63  switch (aDesc.type()) {
     64 #ifdef MOZ_WIDGET_ANDROID
     65    case SurfaceDescriptor::TSurfaceTextureDescriptor: {
     66      const SurfaceTextureDescriptor& desc =
     67          aDesc.get_SurfaceTextureDescriptor();
     68      java::GeckoSurfaceTexture::LocalRef surfaceTexture =
     69          java::GeckoSurfaceTexture::Lookup(desc.handle());
     70 
     71      result = new SurfaceTextureHost(
     72          aFlags, surfaceTexture, desc.size(), desc.format(), desc.continuous(),
     73          desc.forceBT709ColorSpace(), desc.transformOverride());
     74      break;
     75    }
     76    case SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer: {
     77      const SurfaceDescriptorAndroidHardwareBuffer& desc =
     78          aDesc.get_SurfaceDescriptorAndroidHardwareBuffer();
     79      result = AndroidHardwareBufferTextureHost::Create(aFlags, desc);
     80      break;
     81    }
     82 #endif
     83 
     84    case SurfaceDescriptor::TEGLImageDescriptor: {
     85      const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor();
     86      result = new EGLImageTextureHost(aFlags, (EGLImage)desc.image(),
     87                                       (EGLSync)desc.fence(), desc.size(),
     88                                       desc.hasAlpha());
     89      break;
     90    }
     91 
     92 #ifdef MOZ_WIDGET_GTK
     93    case SurfaceDescriptor::TSurfaceDescriptorDMABuf: {
     94      result = new DMABUFTextureHostOGL(aFlags, aDesc);
     95      if (!result->IsValid()) {
     96        gfxCriticalError() << "DMABuf surface import failed!";
     97        result = nullptr;
     98      }
     99      break;
    100    }
    101 #endif
    102 
    103 #ifdef XP_MACOSX
    104    case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
    105      const SurfaceDescriptorMacIOSurface& desc =
    106          aDesc.get_SurfaceDescriptorMacIOSurface();
    107      result = new MacIOSurfaceTextureHostOGL(aFlags, desc);
    108      break;
    109    }
    110 #endif
    111 
    112    case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
    113      const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
    114      result =
    115          new GLTextureHost(aFlags, desc.texture(), desc.target(),
    116                            (GLsync)desc.fence(), desc.size(), desc.hasAlpha());
    117      break;
    118    }
    119    default: {
    120      MOZ_ASSERT_UNREACHABLE("Unsupported SurfaceDescriptor type");
    121      break;
    122    }
    123  }
    124  return result.forget();
    125 }
    126 
    127 static gl::TextureImage::Flags FlagsToGLFlags(TextureFlags aFlags) {
    128  uint32_t result = TextureImage::NoFlags;
    129 
    130  if (aFlags & TextureFlags::USE_NEAREST_FILTER)
    131    result |= TextureImage::UseNearestFilter;
    132  if (aFlags & TextureFlags::ORIGIN_BOTTOM_LEFT)
    133    result |= TextureImage::OriginBottomLeft;
    134  if (aFlags & TextureFlags::DISALLOW_BIGIMAGE)
    135    result |= TextureImage::DisallowBigImage;
    136 
    137  return static_cast<gl::TextureImage::Flags>(result);
    138 }
    139 
    140 TextureImageTextureSourceOGL::TextureImageTextureSourceOGL(
    141    CompositorOGL* aCompositor, TextureFlags aFlags)
    142    : mGL(aCompositor->gl()),
    143      mCompositor(aCompositor),
    144      mFlags(aFlags),
    145      mIterating(false) {
    146  if (mCompositor) {
    147    mCompositor->RegisterTextureSource(this);
    148  }
    149 }
    150 
    151 TextureImageTextureSourceOGL::~TextureImageTextureSourceOGL() {
    152  DeallocateDeviceData();
    153 }
    154 
    155 void TextureImageTextureSourceOGL::DeallocateDeviceData() {
    156  mTexImage = nullptr;
    157  mGL = nullptr;
    158  if (mCompositor) {
    159    mCompositor->UnregisterTextureSource(this);
    160  }
    161  SetUpdateSerial(0);
    162 }
    163 
    164 bool TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
    165                                          nsIntRegion* aDestRegion,
    166                                          gfx::IntPoint* aSrcOffset,
    167                                          gfx::IntPoint* aDstOffset) {
    168  GLContext* gl = mGL;
    169  MOZ_ASSERT(gl);
    170  if (!gl || !gl->MakeCurrent()) {
    171    NS_WARNING(
    172        "trying to update TextureImageTextureSourceOGL without a GLContext");
    173    return false;
    174  }
    175  if (!aSurface) {
    176    gfxCriticalError() << "Invalid surface for OGL update";
    177    return false;
    178  }
    179  MOZ_ASSERT(aSurface);
    180 
    181  IntSize size = aSurface->GetSize();
    182  if (!mTexImage || (mTexImage->GetSize() != size && !aSrcOffset) ||
    183      mTexImage->GetContentType() !=
    184          gfx::ContentForFormat(aSurface->GetFormat())) {
    185    if (mFlags & TextureFlags::DISALLOW_BIGIMAGE) {
    186      GLint maxTextureSize;
    187      gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTextureSize);
    188      if (size.width > maxTextureSize || size.height > maxTextureSize) {
    189        NS_WARNING("Texture exceeds maximum texture size, refusing upload");
    190        return false;
    191      }
    192      // Explicitly use CreateBasicTextureImage instead of CreateTextureImage,
    193      // because CreateTextureImage might still choose to create a tiled
    194      // texture image.
    195      mTexImage = CreateBasicTextureImage(
    196          gl, size, gfx::ContentForFormat(aSurface->GetFormat()),
    197          LOCAL_GL_CLAMP_TO_EDGE, FlagsToGLFlags(mFlags));
    198    } else {
    199      // XXX - clarify which size we want to use. IncrementalContentHost will
    200      // require the size of the destination surface to be different from
    201      // the size of aSurface.
    202      // See bug 893300 (tracks the implementation of ContentHost for new
    203      // textures).
    204      mTexImage = CreateTextureImage(
    205          gl, size, gfx::ContentForFormat(aSurface->GetFormat()),
    206          LOCAL_GL_CLAMP_TO_EDGE, FlagsToGLFlags(mFlags),
    207          SurfaceFormatToImageFormat(aSurface->GetFormat()));
    208    }
    209    ClearCachedFilter();
    210 
    211    if (aDestRegion && !aSrcOffset &&
    212        !aDestRegion->IsEqual(gfx::IntRect(0, 0, size.width, size.height))) {
    213      // UpdateFromDataSource will ignore our specified aDestRegion since the
    214      // texture hasn't been allocated with glTexImage2D yet. Call Resize() to
    215      // force the allocation (full size, but no upload), and then we'll only
    216      // upload the pixels we care about below.
    217      mTexImage->Resize(size);
    218    }
    219  }
    220 
    221  return mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset,
    222                                         aDstOffset);
    223 }
    224 
    225 void TextureImageTextureSourceOGL::EnsureBuffer(const IntSize& aSize,
    226                                                gfxContentType aContentType) {
    227  if (!mTexImage || mTexImage->GetSize() != aSize ||
    228      mTexImage->GetContentType() != aContentType) {
    229    mTexImage =
    230        CreateTextureImage(mGL, aSize, aContentType, LOCAL_GL_CLAMP_TO_EDGE,
    231                           FlagsToGLFlags(mFlags));
    232  }
    233  mTexImage->Resize(aSize);
    234 }
    235 
    236 gfx::IntSize TextureImageTextureSourceOGL::GetSize() const {
    237  if (mTexImage) {
    238    if (mIterating) {
    239      return mTexImage->GetTileRect().Size();
    240    }
    241    return mTexImage->GetSize();
    242  }
    243  NS_WARNING("Trying to query the size of an empty TextureSource.");
    244  return gfx::IntSize(0, 0);
    245 }
    246 
    247 gfx::SurfaceFormat TextureImageTextureSourceOGL::GetFormat() const {
    248  if (mTexImage) {
    249    return mTexImage->GetTextureFormat();
    250  }
    251  NS_WARNING("Trying to query the format of an empty TextureSource.");
    252  return gfx::SurfaceFormat::UNKNOWN;
    253 }
    254 
    255 gfx::IntRect TextureImageTextureSourceOGL::GetTileRect() {
    256  return mTexImage->GetTileRect();
    257 }
    258 
    259 void TextureImageTextureSourceOGL::BindTexture(
    260    GLenum aTextureUnit, gfx::SamplingFilter aSamplingFilter) {
    261  MOZ_ASSERT(mTexImage,
    262             "Trying to bind a TextureSource that does not have an underlying "
    263             "GL texture.");
    264  mTexImage->BindTexture(aTextureUnit);
    265  SetSamplingFilter(mGL, aSamplingFilter);
    266 }
    267 
    268 ////////////////////////////////////////////////////////////////////////
    269 // GLTextureSource
    270 
    271 GLTextureSource::GLTextureSource(TextureSourceProvider* aProvider,
    272                                 GLuint aTextureHandle, GLenum aTarget,
    273                                 gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
    274    : GLTextureSource(aProvider->GetGLContext(), aTextureHandle, aTarget, aSize,
    275                      aFormat) {}
    276 
    277 GLTextureSource::GLTextureSource(GLContext* aGL, GLuint aTextureHandle,
    278                                 GLenum aTarget, gfx::IntSize aSize,
    279                                 gfx::SurfaceFormat aFormat)
    280    : mGL(aGL),
    281      mTextureHandle(aTextureHandle),
    282      mTextureTarget(aTarget),
    283      mSize(aSize),
    284      mFormat(aFormat) {
    285  MOZ_COUNT_CTOR(GLTextureSource);
    286 }
    287 
    288 GLTextureSource::~GLTextureSource() {
    289  MOZ_COUNT_DTOR(GLTextureSource);
    290  DeleteTextureHandle();
    291 }
    292 
    293 void GLTextureSource::DeallocateDeviceData() { DeleteTextureHandle(); }
    294 
    295 void GLTextureSource::DeleteTextureHandle() {
    296  GLContext* gl = this->gl();
    297  if (mTextureHandle != 0 && gl && gl->MakeCurrent()) {
    298    gl->fDeleteTextures(1, &mTextureHandle);
    299  }
    300  mTextureHandle = 0;
    301 }
    302 
    303 void GLTextureSource::BindTexture(GLenum aTextureUnit,
    304                                  gfx::SamplingFilter aSamplingFilter) {
    305  MOZ_ASSERT(mTextureHandle != 0);
    306  GLContext* gl = this->gl();
    307  if (!gl || !gl->MakeCurrent()) {
    308    return;
    309  }
    310  gl->fActiveTexture(aTextureUnit);
    311  gl->fBindTexture(mTextureTarget, mTextureHandle);
    312  ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
    313 }
    314 
    315 bool GLTextureSource::IsValid() const { return !!gl() && mTextureHandle != 0; }
    316 
    317 ////////////////////////////////////////////////////////////////////////
    318 // DirectMapTextureSource
    319 
    320 DirectMapTextureSource::DirectMapTextureSource(gl::GLContext* aContext,
    321                                               gfx::DataSourceSurface* aSurface)
    322    : GLTextureSource(aContext, 0, LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    323                      aSurface->GetSize(), aSurface->GetFormat()),
    324      mSync(0) {
    325  MOZ_ASSERT(aSurface);
    326 
    327  UpdateInternal(aSurface, nullptr, nullptr, true);
    328 }
    329 
    330 DirectMapTextureSource::DirectMapTextureSource(TextureSourceProvider* aProvider,
    331                                               gfx::DataSourceSurface* aSurface)
    332    : DirectMapTextureSource(aProvider->GetGLContext(), aSurface) {}
    333 
    334 DirectMapTextureSource::~DirectMapTextureSource() {
    335  if (!mSync || !gl() || !gl()->MakeCurrent() || gl()->IsDestroyed()) {
    336    return;
    337  }
    338 
    339  gl()->fDeleteSync(mSync);
    340  mSync = 0;
    341 }
    342 
    343 bool DirectMapTextureSource::Update(gfx::DataSourceSurface* aSurface,
    344                                    nsIntRegion* aDestRegion,
    345                                    gfx::IntPoint* aSrcOffset,
    346                                    gfx::IntPoint* aDstOffset) {
    347  MOZ_RELEASE_ASSERT(aDstOffset == nullptr);
    348  if (!aSurface) {
    349    return false;
    350  }
    351 
    352  return UpdateInternal(aSurface, aDestRegion, aSrcOffset, false);
    353 }
    354 
    355 void DirectMapTextureSource::MaybeFenceTexture() {
    356  if (!gl() || !gl()->MakeCurrent() || gl()->IsDestroyed()) {
    357    return;
    358  }
    359 
    360  if (mSync) {
    361    gl()->fDeleteSync(mSync);
    362  }
    363  mSync = gl()->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
    364 }
    365 
    366 bool DirectMapTextureSource::Sync(bool aBlocking) {
    367  if (!gl() || !gl()->MakeCurrent() || gl()->IsDestroyed()) {
    368    // We use this function to decide whether we can unlock the texture
    369    // and clean it up. If we return false here and for whatever reason
    370    // the context is absent or invalid, the compositor will keep a
    371    // reference to this texture forever.
    372    return true;
    373  }
    374 
    375  if (!mSync) {
    376    return false;
    377  }
    378 
    379  GLenum waitResult =
    380      gl()->fClientWaitSync(mSync, LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT,
    381                            aBlocking ? LOCAL_GL_TIMEOUT_IGNORED : 0);
    382  return waitResult == LOCAL_GL_ALREADY_SIGNALED ||
    383         waitResult == LOCAL_GL_CONDITION_SATISFIED;
    384 }
    385 
    386 bool DirectMapTextureSource::UpdateInternal(gfx::DataSourceSurface* aSurface,
    387                                            nsIntRegion* aDestRegion,
    388                                            gfx::IntPoint* aSrcOffset,
    389                                            bool aInit) {
    390  if (!gl() || !gl()->MakeCurrent()) {
    391    return false;
    392  }
    393 
    394  if (aInit) {
    395    gl()->fGenTextures(1, &mTextureHandle);
    396    gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, mTextureHandle);
    397 
    398    gl()->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    399                         LOCAL_GL_TEXTURE_STORAGE_HINT_APPLE,
    400                         LOCAL_GL_STORAGE_CACHED_APPLE);
    401    gl()->fTextureRangeAPPLE(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    402                             aSurface->Stride() * aSurface->GetSize().height,
    403                             aSurface->GetData());
    404 
    405    gl()->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    406                         LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
    407    gl()->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    408                         LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
    409  }
    410 
    411  MOZ_ASSERT(mTextureHandle);
    412 
    413  // APPLE_client_storage
    414  gl()->fPixelStorei(LOCAL_GL_UNPACK_CLIENT_STORAGE_APPLE, LOCAL_GL_TRUE);
    415 
    416  nsIntRegion destRegion = aDestRegion
    417                               ? *aDestRegion
    418                               : IntRect(0, 0, aSurface->GetSize().width,
    419                                         aSurface->GetSize().height);
    420  gfx::IntPoint srcPoint = aSrcOffset ? *aSrcOffset : gfx::IntPoint(0, 0);
    421  mFormat = gl::UploadSurfaceToTexture(
    422      gl(), aSurface, destRegion, mTextureHandle, aSurface->GetSize(), nullptr,
    423      aInit, srcPoint, gfx::IntPoint(0, 0), LOCAL_GL_TEXTURE0,
    424      LOCAL_GL_TEXTURE_RECTANGLE_ARB);
    425 
    426  if (mSync) {
    427    gl()->fDeleteSync(mSync);
    428    mSync = 0;
    429  }
    430 
    431  gl()->fPixelStorei(LOCAL_GL_UNPACK_CLIENT_STORAGE_APPLE, LOCAL_GL_FALSE);
    432  return true;
    433 }
    434 
    435 ////////////////////////////////////////////////////////////////////////
    436 ////////////////////////////////////////////////////////////////////////
    437 // SurfaceTextureHost
    438 
    439 #ifdef MOZ_WIDGET_ANDROID
    440 
    441 SurfaceTextureSource::SurfaceTextureSource(
    442    TextureSourceProvider* aProvider,
    443    mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
    444    gfx::SurfaceFormat aFormat, GLenum aTarget, GLenum aWrapMode,
    445    gfx::IntSize aSize, Maybe<gfx::Matrix4x4> aTransformOverride)
    446    : mGL(aProvider->GetGLContext()),
    447      mSurfTex(aSurfTex),
    448      mFormat(aFormat),
    449      mTextureTarget(aTarget),
    450      mWrapMode(aWrapMode),
    451      mSize(aSize),
    452      mTransformOverride(aTransformOverride) {}
    453 
    454 void SurfaceTextureSource::BindTexture(GLenum aTextureUnit,
    455                                       gfx::SamplingFilter aSamplingFilter) {
    456  MOZ_ASSERT(mSurfTex);
    457  GLContext* gl = this->gl();
    458  if (!gl || !gl->MakeCurrent()) {
    459    NS_WARNING("Trying to bind a texture without a GLContext");
    460    return;
    461  }
    462 
    463  gl->fActiveTexture(aTextureUnit);
    464  gl->fBindTexture(mTextureTarget, mSurfTex->GetTexName());
    465 
    466  ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
    467 }
    468 
    469 bool SurfaceTextureSource::IsValid() const { return !!gl(); }
    470 
    471 gfx::Matrix4x4 SurfaceTextureSource::GetTextureTransform() {
    472  MOZ_ASSERT(mSurfTex);
    473 
    474  gfx::Matrix4x4 ret;
    475 
    476  // GetTransformMatrix() returns the transform set by the producer side of the
    477  // SurfaceTexture that must be applied to texture coordinates when
    478  // sampling. In some cases we may have set an override value, such as in
    479  // AndroidNativeWindowTextureData where we own the producer side, or for
    480  // MediaCodec output on devices where where we know the value is incorrect.
    481  if (mTransformOverride) {
    482    ret = *mTransformOverride;
    483  } else {
    484    const auto& surf = java::sdk::SurfaceTexture::LocalRef(
    485        java::sdk::SurfaceTexture::Ref::From(mSurfTex));
    486    AndroidSurfaceTexture::GetTransformMatrix(surf, &ret);
    487  }
    488 
    489  return ret;
    490 }
    491 
    492 void SurfaceTextureSource::DeallocateDeviceData() { mSurfTex = nullptr; }
    493 
    494 ////////////////////////////////////////////////////////////////////////
    495 
    496 SurfaceTextureHost::SurfaceTextureHost(
    497    TextureFlags aFlags, mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
    498    gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aContinuousUpdate,
    499    bool aForceBT709ColorSpace, Maybe<Matrix4x4> aTransformOverride)
    500    : TextureHost(TextureHostType::AndroidSurfaceTexture, aFlags),
    501      mSurfTex(aSurfTex),
    502      mSize(aSize),
    503      mFormat(aFormat),
    504      mContinuousUpdate(aContinuousUpdate),
    505      mForceBT709ColorSpace(aForceBT709ColorSpace),
    506      mTransformOverride(aTransformOverride) {
    507  if (!mSurfTex) {
    508    return;
    509  }
    510 
    511  // Continuous update makes no sense with single buffer mode
    512  MOZ_ASSERT(!mSurfTex->IsSingleBuffer() || !mContinuousUpdate);
    513 
    514  mSurfTex->IncrementUse();
    515 }
    516 
    517 SurfaceTextureHost::~SurfaceTextureHost() {
    518  if (mSurfTex) {
    519    mSurfTex->DecrementUse();
    520    mSurfTex = nullptr;
    521  }
    522 }
    523 
    524 gl::GLContext* SurfaceTextureHost::gl() const { return nullptr; }
    525 
    526 gfx::SurfaceFormat SurfaceTextureHost::GetFormat() const { return mFormat; }
    527 
    528 void SurfaceTextureHost::DeallocateDeviceData() {
    529  if (mTextureSource) {
    530    mTextureSource->DeallocateDeviceData();
    531  }
    532 
    533  if (mSurfTex) {
    534    mSurfTex->DecrementUse();
    535    mSurfTex = nullptr;
    536  }
    537 }
    538 
    539 void SurfaceTextureHost::CreateRenderTexture(
    540    const wr::ExternalImageId& aExternalImageId) {
    541  MOZ_ASSERT(mExternalImageId.isSome());
    542 
    543  bool isRemoteTexture = !!(mFlags & TextureFlags::REMOTE_TEXTURE);
    544  RefPtr<wr::RenderTextureHost> texture =
    545      new wr::RenderAndroidSurfaceTextureHost(
    546          mSurfTex, mSize, mFormat, mContinuousUpdate, mTransformOverride,
    547          isRemoteTexture);
    548  wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId,
    549                                                 texture.forget());
    550 }
    551 
    552 uint32_t SurfaceTextureHost::NumSubTextures() { return mSurfTex ? 1 : 0; }
    553 
    554 void SurfaceTextureHost::PushResourceUpdates(
    555    wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
    556    const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) {
    557  auto method = aOp == TextureHost::ADD_IMAGE
    558                    ? &wr::TransactionBuilder::AddExternalImage
    559                    : &wr::TransactionBuilder::UpdateExternalImage;
    560 
    561  // Prefer TextureExternal unless the backend requires TextureRect.
    562  TextureHost::NativeTexturePolicy policy =
    563      TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
    564                                              GetSize());
    565  auto imageType = wr::ExternalImageType::TextureHandle(
    566      wr::ImageBufferKind::TextureExternal);
    567  if (policy == TextureHost::NativeTexturePolicy::REQUIRE) {
    568    imageType =
    569        wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::TextureRect);
    570  } else if (mForceBT709ColorSpace) {
    571    imageType = wr::ExternalImageType::TextureHandle(
    572        wr::ImageBufferKind::TextureExternalBT709);
    573  }
    574 
    575  // Hardware webrender directly renders from the SurfaceTexture therefore we
    576  // must provide it the (transformed) normalized UVs. For software webrender we
    577  // first read from the SurfaceTexture in to a CPU buffer, which we sample from
    578  // using unnormalized UVs. The readback code handles the texture transform.
    579  // See RenderAndroidSurfaceTextureHost::Lock() and
    580  // RenderAndroidSurfaceTextureHost::ReadTexImage(), respectively.
    581  const bool normalizedUvs =
    582      aResources.GetBackendType() == WebRenderBackend::HARDWARE;
    583 
    584  switch (GetFormat()) {
    585    case gfx::SurfaceFormat::R8G8B8X8:
    586    case gfx::SurfaceFormat::R8G8B8A8: {
    587      MOZ_ASSERT(aImageKeys.length() == 1);
    588 
    589      // XXX Add RGBA handling. Temporary hack to avoid crash
    590      // With BGRA format setting, rendering works without problem.
    591      auto format = GetFormat() == gfx::SurfaceFormat::R8G8B8A8
    592                        ? gfx::SurfaceFormat::B8G8R8A8
    593                        : gfx::SurfaceFormat::B8G8R8X8;
    594      wr::ImageDescriptor descriptor(GetSize(), format);
    595      (aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0,
    596                           normalizedUvs);
    597      break;
    598    }
    599    default: {
    600      MOZ_ASSERT_UNREACHABLE("unexpected to be called");
    601    }
    602  }
    603 }
    604 
    605 void SurfaceTextureHost::PushDisplayItems(wr::DisplayListBuilder& aBuilder,
    606                                          const wr::LayoutRect& aBounds,
    607                                          const wr::LayoutRect& aClip,
    608                                          wr::ImageRendering aFilter,
    609                                          const Range<wr::ImageKey>& aImageKeys,
    610                                          PushDisplayItemFlagSet aFlags) {
    611  bool preferCompositorSurface =
    612      aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE);
    613  bool supportsExternalCompositing =
    614      SupportsExternalCompositing(aBuilder.GetBackendType());
    615 
    616  switch (GetFormat()) {
    617    case gfx::SurfaceFormat::R8G8B8X8:
    618    case gfx::SurfaceFormat::R8G8B8A8:
    619    case gfx::SurfaceFormat::B8G8R8A8:
    620    case gfx::SurfaceFormat::B8G8R8X8: {
    621      MOZ_ASSERT(aImageKeys.length() == 1);
    622      aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0],
    623                         !(mFlags & TextureFlags::NON_PREMULTIPLIED),
    624                         wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
    625                         preferCompositorSurface, supportsExternalCompositing);
    626      break;
    627    }
    628    default: {
    629      MOZ_ASSERT_UNREACHABLE("unexpected to be called");
    630    }
    631  }
    632 }
    633 
    634 bool SurfaceTextureHost::SupportsExternalCompositing(
    635    WebRenderBackend aBackend) {
    636  return aBackend == WebRenderBackend::SOFTWARE;
    637 }
    638 
    639 ////////////////////////////////////////////////////////////////////////
    640 // AndroidHardwareBufferTextureSource
    641 
    642 AndroidHardwareBufferTextureSource::AndroidHardwareBufferTextureSource(
    643    TextureSourceProvider* aProvider,
    644    AndroidHardwareBuffer* aAndroidHardwareBuffer, gfx::SurfaceFormat aFormat,
    645    GLenum aTarget, GLenum aWrapMode, gfx::IntSize aSize)
    646    : mGL(aProvider->GetGLContext()),
    647      mAndroidHardwareBuffer(aAndroidHardwareBuffer),
    648      mFormat(aFormat),
    649      mTextureTarget(aTarget),
    650      mWrapMode(aWrapMode),
    651      mSize(aSize),
    652      mEGLImage(EGL_NO_IMAGE),
    653      mTextureHandle(0) {}
    654 
    655 AndroidHardwareBufferTextureSource::~AndroidHardwareBufferTextureSource() {
    656  DeleteTextureHandle();
    657  DestroyEGLImage();
    658 }
    659 
    660 bool AndroidHardwareBufferTextureSource::EnsureEGLImage() {
    661  if (!mAndroidHardwareBuffer) {
    662    return false;
    663  }
    664 
    665  auto fenceFd = mAndroidHardwareBuffer->GetAndResetAcquireFence();
    666  if (fenceFd) {
    667    const auto& gle = gl::GLContextEGL::Cast(mGL);
    668    const auto& egl = gle->mEgl;
    669 
    670    const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
    671                              fenceFd.get(), LOCAL_EGL_NONE};
    672 
    673    EGLSync sync =
    674        egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
    675    if (sync) {
    676      // Release fd here, since it is owned by EGLSync
    677      (void)fenceFd.release();
    678 
    679      if (egl->IsExtensionSupported(gl::EGLExtension::KHR_wait_sync)) {
    680        egl->fWaitSync(sync, 0);
    681      } else {
    682        egl->fClientWaitSync(sync, 0, LOCAL_EGL_FOREVER);
    683      }
    684      egl->fDestroySync(sync);
    685    } else {
    686      gfxCriticalNote << "Failed to create EGLSync from acquire fence fd";
    687    }
    688  }
    689 
    690  if (mTextureHandle) {
    691    return true;
    692  }
    693 
    694  if (!mEGLImage) {
    695    // XXX add crop handling for video
    696    // Should only happen the first time.
    697    const auto& gle = gl::GLContextEGL::Cast(mGL);
    698    const auto& egl = gle->mEgl;
    699 
    700    const EGLint attrs[] = {
    701        LOCAL_EGL_IMAGE_PRESERVED,
    702        LOCAL_EGL_TRUE,
    703        LOCAL_EGL_NONE,
    704        LOCAL_EGL_NONE,
    705    };
    706 
    707    EGLClientBuffer clientBuffer = egl->mLib->fGetNativeClientBufferANDROID(
    708        mAndroidHardwareBuffer->GetNativeBuffer());
    709    mEGLImage = egl->fCreateImage(
    710        EGL_NO_CONTEXT, LOCAL_EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs);
    711  }
    712  MOZ_ASSERT(mEGLImage);
    713 
    714  mGL->fGenTextures(1, &mTextureHandle);
    715  mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, mTextureHandle);
    716  mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL, LOCAL_GL_TEXTURE_WRAP_T,
    717                      LOCAL_GL_CLAMP_TO_EDGE);
    718  mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL, LOCAL_GL_TEXTURE_WRAP_S,
    719                      LOCAL_GL_CLAMP_TO_EDGE);
    720  mGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mEGLImage);
    721 
    722  return true;
    723 }
    724 
    725 void AndroidHardwareBufferTextureSource::DeleteTextureHandle() {
    726  if (!mTextureHandle) {
    727    return;
    728  }
    729  MOZ_ASSERT(mGL);
    730  mGL->fDeleteTextures(1, &mTextureHandle);
    731  mTextureHandle = 0;
    732 }
    733 
    734 void AndroidHardwareBufferTextureSource::DestroyEGLImage() {
    735  if (!mEGLImage) {
    736    return;
    737  }
    738  MOZ_ASSERT(mGL);
    739  const auto& gle = gl::GLContextEGL::Cast(mGL);
    740  const auto& egl = gle->mEgl;
    741  egl->fDestroyImage(mEGLImage);
    742  mEGLImage = EGL_NO_IMAGE;
    743 }
    744 
    745 void AndroidHardwareBufferTextureSource::BindTexture(
    746    GLenum aTextureUnit, gfx::SamplingFilter aSamplingFilter) {
    747  MOZ_ASSERT(mAndroidHardwareBuffer);
    748  GLContext* gl = this->gl();
    749  if (!gl || !gl->MakeCurrent()) {
    750    NS_WARNING("Trying to bind a texture without a GLContext");
    751    return;
    752  }
    753 
    754  if (!EnsureEGLImage()) {
    755    return;
    756  }
    757 
    758  gl->fActiveTexture(aTextureUnit);
    759  gl->fBindTexture(mTextureTarget, mTextureHandle);
    760 
    761  ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
    762 }
    763 
    764 bool AndroidHardwareBufferTextureSource::IsValid() const { return !!gl(); }
    765 
    766 void AndroidHardwareBufferTextureSource::DeallocateDeviceData() {
    767  DestroyEGLImage();
    768  DeleteTextureHandle();
    769  mAndroidHardwareBuffer = nullptr;
    770 }
    771 
    772 ////////////////////////////////////////////////////////////////////////
    773 // AndroidHardwareBufferTextureHost
    774 
    775 /* static */
    776 already_AddRefed<AndroidHardwareBufferTextureHost>
    777 AndroidHardwareBufferTextureHost::Create(
    778    TextureFlags aFlags, const SurfaceDescriptorAndroidHardwareBuffer& aDesc) {
    779  RefPtr<AndroidHardwareBuffer> buffer =
    780      AndroidHardwareBufferManager::Get()->GetBuffer(aDesc.bufferId());
    781  if (!buffer) {
    782    return nullptr;
    783  }
    784  RefPtr<AndroidHardwareBufferTextureHost> host =
    785      new AndroidHardwareBufferTextureHost(aFlags, buffer);
    786  return host.forget();
    787 }
    788 
    789 AndroidHardwareBufferTextureHost::AndroidHardwareBufferTextureHost(
    790    TextureFlags aFlags, AndroidHardwareBuffer* aAndroidHardwareBuffer)
    791    : TextureHost(TextureHostType::AndroidHardwareBuffer, aFlags),
    792      mAndroidHardwareBuffer(aAndroidHardwareBuffer) {
    793  MOZ_ASSERT(mAndroidHardwareBuffer);
    794 }
    795 
    796 AndroidHardwareBufferTextureHost::~AndroidHardwareBufferTextureHost() {}
    797 
    798 gl::GLContext* AndroidHardwareBufferTextureHost::gl() const { return nullptr; }
    799 
    800 void AndroidHardwareBufferTextureHost::NotifyNotUsed() {
    801  TextureHost::NotifyNotUsed();
    802 }
    803 
    804 gfx::SurfaceFormat AndroidHardwareBufferTextureHost::GetFormat() const {
    805  if (mAndroidHardwareBuffer) {
    806    return mAndroidHardwareBuffer->mFormat;
    807  }
    808  return gfx::SurfaceFormat::UNKNOWN;
    809 }
    810 
    811 gfx::IntSize AndroidHardwareBufferTextureHost::GetSize() const {
    812  if (mAndroidHardwareBuffer) {
    813    return mAndroidHardwareBuffer->mSize;
    814  }
    815  return gfx::IntSize();
    816 }
    817 
    818 void AndroidHardwareBufferTextureHost::DeallocateDeviceData() {
    819  mAndroidHardwareBuffer = nullptr;
    820 }
    821 
    822 void AndroidHardwareBufferTextureHost::SetReadFence(Fence* aReadFence) {
    823  MOZ_ASSERT(aReadFence);
    824  MOZ_ASSERT(aReadFence->AsFenceFileHandle());
    825  MOZ_ASSERT(mAndroidHardwareBuffer);
    826 
    827  if (!aReadFence || !aReadFence->AsFenceFileHandle() ||
    828      !mAndroidHardwareBuffer) {
    829    return;
    830  }
    831 
    832  UniqueFileHandle handle =
    833      aReadFence->AsFenceFileHandle()->DuplicateFileHandle();
    834  mAndroidHardwareBuffer->SetReleaseFence(std::move(handle));
    835 }
    836 
    837 void AndroidHardwareBufferTextureHost::CreateRenderTexture(
    838    const wr::ExternalImageId& aExternalImageId) {
    839  MOZ_ASSERT(mExternalImageId.isSome());
    840 
    841  RefPtr<wr::RenderTextureHost> texture =
    842      new wr::RenderAndroidHardwareBufferTextureHost(mAndroidHardwareBuffer);
    843  wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId,
    844                                                 texture.forget());
    845 }
    846 
    847 uint32_t AndroidHardwareBufferTextureHost::NumSubTextures() {
    848  return mAndroidHardwareBuffer ? 1 : 0;
    849 }
    850 
    851 void AndroidHardwareBufferTextureHost::PushResourceUpdates(
    852    wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
    853    const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) {
    854  auto method = aOp == TextureHost::ADD_IMAGE
    855                    ? &wr::TransactionBuilder::AddExternalImage
    856                    : &wr::TransactionBuilder::UpdateExternalImage;
    857 
    858  // Prefer TextureExternal unless the backend requires TextureRect.
    859  TextureHost::NativeTexturePolicy policy =
    860      TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
    861                                              GetSize());
    862  auto imageType = policy == TextureHost::NativeTexturePolicy::REQUIRE
    863                       ? wr::ExternalImageType::TextureHandle(
    864                             wr::ImageBufferKind::TextureRect)
    865                       : wr::ExternalImageType::TextureHandle(
    866                             wr::ImageBufferKind::TextureExternal);
    867 
    868  switch (GetFormat()) {
    869    case gfx::SurfaceFormat::R8G8B8X8:
    870    case gfx::SurfaceFormat::R8G8B8A8: {
    871      MOZ_ASSERT(aImageKeys.length() == 1);
    872 
    873      // XXX Add RGBA handling. Temporary hack to avoid crash
    874      // With BGRA format setting, rendering works without problem.
    875      auto format = GetFormat() == gfx::SurfaceFormat::R8G8B8A8
    876                        ? gfx::SurfaceFormat::B8G8R8A8
    877                        : gfx::SurfaceFormat::B8G8R8X8;
    878      wr::ImageDescriptor descriptor(GetSize(), format);
    879      (aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0,
    880                           /* aNormalizedUvs */ false);
    881      break;
    882    }
    883    default: {
    884      MOZ_ASSERT_UNREACHABLE("unexpected to be called");
    885    }
    886  }
    887 }
    888 
    889 void AndroidHardwareBufferTextureHost::PushDisplayItems(
    890    wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
    891    const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
    892    const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) {
    893  bool preferCompositorSurface =
    894      aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE);
    895  bool supportsExternalCompositing =
    896      SupportsExternalCompositing(aBuilder.GetBackendType());
    897 
    898  switch (GetFormat()) {
    899    case gfx::SurfaceFormat::R8G8B8X8:
    900    case gfx::SurfaceFormat::R8G8B8A8:
    901    case gfx::SurfaceFormat::B8G8R8A8:
    902    case gfx::SurfaceFormat::B8G8R8X8: {
    903      MOZ_ASSERT(aImageKeys.length() == 1);
    904      aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0],
    905                         !(mFlags & TextureFlags::NON_PREMULTIPLIED),
    906                         wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
    907                         preferCompositorSurface, supportsExternalCompositing);
    908      break;
    909    }
    910    default: {
    911      MOZ_ASSERT_UNREACHABLE("unexpected to be called");
    912    }
    913  }
    914 }
    915 
    916 bool AndroidHardwareBufferTextureHost::SupportsExternalCompositing(
    917    WebRenderBackend aBackend) {
    918  return aBackend == WebRenderBackend::SOFTWARE;
    919 }
    920 
    921 #endif  // MOZ_WIDGET_ANDROID
    922 
    923 ////////////////////////////////////////////////////////////////////////
    924 ////////////////////////////////////////////////////////////////////////
    925 // EGLImage
    926 
    927 EGLImageTextureSource::EGLImageTextureSource(TextureSourceProvider* aProvider,
    928                                             EGLImage aImage,
    929                                             gfx::SurfaceFormat aFormat,
    930                                             GLenum aTarget, GLenum aWrapMode,
    931                                             gfx::IntSize aSize)
    932    : mGL(aProvider->GetGLContext()),
    933      mCompositor(aProvider->AsCompositorOGL()),
    934      mImage(aImage),
    935      mFormat(aFormat),
    936      mTextureTarget(aTarget),
    937      mWrapMode(aWrapMode),
    938      mSize(aSize) {
    939  MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
    940             mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
    941 }
    942 
    943 void EGLImageTextureSource::BindTexture(GLenum aTextureUnit,
    944                                        gfx::SamplingFilter aSamplingFilter) {
    945  GLContext* gl = this->gl();
    946  if (!gl || !gl->MakeCurrent()) {
    947    NS_WARNING("Trying to bind a texture without a GLContext");
    948    return;
    949  }
    950 
    951 #ifdef DEBUG
    952  const bool supportsEglImage = [&]() {
    953    const auto& gle = GLContextEGL::Cast(gl);
    954    const auto& egl = gle->mEgl;
    955 
    956    return egl->HasKHRImageBase() &&
    957           egl->IsExtensionSupported(EGLExtension::KHR_gl_texture_2D_image) &&
    958           gl->IsExtensionSupported(GLContext::OES_EGL_image);
    959  }();
    960  MOZ_ASSERT(supportsEglImage, "EGLImage not supported or disabled in runtime");
    961 #endif
    962 
    963  GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit);
    964 
    965  gl->fActiveTexture(aTextureUnit);
    966  gl->fBindTexture(mTextureTarget, tex);
    967 
    968  gl->fEGLImageTargetTexture2D(mTextureTarget, mImage);
    969 
    970  ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
    971 }
    972 
    973 bool EGLImageTextureSource::IsValid() const { return !!gl(); }
    974 
    975 gfx::Matrix4x4 EGLImageTextureSource::GetTextureTransform() {
    976  gfx::Matrix4x4 ret;
    977  return ret;
    978 }
    979 
    980 ////////////////////////////////////////////////////////////////////////
    981 
    982 EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags, EGLImage aImage,
    983                                         EGLSync aSync, gfx::IntSize aSize,
    984                                         bool hasAlpha)
    985    : TextureHost(TextureHostType::EGLImage, aFlags),
    986      mImage(aImage),
    987      mSync(aSync),
    988      mSize(aSize),
    989      mHasAlpha(hasAlpha) {}
    990 
    991 EGLImageTextureHost::~EGLImageTextureHost() = default;
    992 
    993 gl::GLContext* EGLImageTextureHost::gl() const { return nullptr; }
    994 
    995 gfx::SurfaceFormat EGLImageTextureHost::GetFormat() const {
    996  return mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
    997                   : gfx::SurfaceFormat::R8G8B8X8;
    998 }
    999 
   1000 void EGLImageTextureHost::CreateRenderTexture(
   1001    const wr::ExternalImageId& aExternalImageId) {
   1002  MOZ_ASSERT(mExternalImageId.isSome());
   1003 
   1004  RefPtr<wr::RenderTextureHost> texture =
   1005      new wr::RenderEGLImageTextureHost(mImage, mSync, mSize, GetFormat());
   1006  wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId,
   1007                                                 texture.forget());
   1008 }
   1009 
   1010 void EGLImageTextureHost::PushResourceUpdates(
   1011    wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
   1012    const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) {
   1013  auto method = aOp == TextureHost::ADD_IMAGE
   1014                    ? &wr::TransactionBuilder::AddExternalImage
   1015                    : &wr::TransactionBuilder::UpdateExternalImage;
   1016 
   1017  // Prefer TextureExternal unless the backend requires TextureRect.
   1018  TextureHost::NativeTexturePolicy policy =
   1019      TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
   1020                                              GetSize());
   1021  auto imageType = policy == TextureHost::NativeTexturePolicy::REQUIRE
   1022                       ? wr::ExternalImageType::TextureHandle(
   1023                             wr::ImageBufferKind::TextureRect)
   1024                       : wr::ExternalImageType::TextureHandle(
   1025                             wr::ImageBufferKind::TextureExternal);
   1026 
   1027  gfx::SurfaceFormat format = GetFormat();
   1028 
   1029  MOZ_ASSERT(aImageKeys.length() == 1);
   1030  // XXX Add RGBA handling. Temporary hack to avoid crash
   1031  // With BGRA format setting, rendering works without problem.
   1032  auto formatTmp = format == gfx::SurfaceFormat::R8G8B8A8
   1033                       ? gfx::SurfaceFormat::B8G8R8A8
   1034                       : gfx::SurfaceFormat::B8G8R8X8;
   1035  wr::ImageDescriptor descriptor(GetSize(), formatTmp);
   1036  (aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0,
   1037                       /* aNormalizedUvs */ false);
   1038 }
   1039 
   1040 void EGLImageTextureHost::PushDisplayItems(
   1041    wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
   1042    const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
   1043    const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) {
   1044  bool preferCompositorSurface =
   1045      aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE);
   1046  bool supportsExternalCompositing =
   1047      SupportsExternalCompositing(aBuilder.GetBackendType());
   1048 
   1049  MOZ_ASSERT(aImageKeys.length() == 1);
   1050  aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0],
   1051                     !(mFlags & TextureFlags::NON_PREMULTIPLIED),
   1052                     wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
   1053                     preferCompositorSurface, supportsExternalCompositing);
   1054 }
   1055 
   1056 bool EGLImageTextureHost::SupportsExternalCompositing(
   1057    WebRenderBackend aBackend) {
   1058  return aBackend == WebRenderBackend::SOFTWARE;
   1059 }
   1060 
   1061 //
   1062 
   1063 GLTextureHost::GLTextureHost(TextureFlags aFlags, GLuint aTextureHandle,
   1064                             GLenum aTarget, GLsync aSync, gfx::IntSize aSize,
   1065                             bool aHasAlpha)
   1066    : TextureHost(TextureHostType::GLTexture, aFlags),
   1067      mTexture(aTextureHandle),
   1068      mTarget(aTarget),
   1069      mSync(aSync),
   1070      mSize(aSize),
   1071      mHasAlpha(aHasAlpha) {}
   1072 
   1073 GLTextureHost::~GLTextureHost() = default;
   1074 
   1075 gl::GLContext* GLTextureHost::gl() const { return nullptr; }
   1076 
   1077 gfx::SurfaceFormat GLTextureHost::GetFormat() const {
   1078  MOZ_ASSERT(mTextureSource);
   1079  return mTextureSource ? mTextureSource->GetFormat()
   1080                        : gfx::SurfaceFormat::UNKNOWN;
   1081 }
   1082 
   1083 }  // namespace layers
   1084 }  // namespace mozilla