Bug 1898238 - Make SharedSurface_EGLImage and (Render)EGLImageTextureHost work. r=sotaro,jgilbert
SharedSurface_EGLImage has mostly avoided bitrotting. However, it now sometimes gets destructed after the GLContext has been lost, resulting in a crash when attempting to clean up its resources. To avoid this, we hold a weak reference to the EglDisplay, and use that to clean up rather than the GLContext. To support rendering with SWGL, EGLImageTextureHost ensures the correct preferCompositorSurface, supportsExternalCompositing, and imageType values are sent to webrender. RenderEGLImageTextureHost now implements RenderTextureHostSWGL, as well as the new CreateTextureSource() function, and EGLImageTextureSource is initialized with a GL context reference so that it may actually work. Additionally we use eglWaitSync() rather than eglClientWaitSync() where available for improved performance. And we ensure that we bind the EGL images' textures to GL_TEXTURE_2D rather than GL_TEXTURE_EXTERNAL when running on the Android emulator to work around the buggy implementation in some emulator versions. Differential Revision: https://phabricator.services.mozilla.com/D211291
This commit is contained in:
@@ -3578,9 +3578,11 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
return LOCAL_GL_TEXTURE_2D;
|
||||
#else
|
||||
return IsExtensionSupported(OES_EGL_image_external)
|
||||
? LOCAL_GL_TEXTURE_EXTERNAL
|
||||
: LOCAL_GL_TEXTURE_2D;
|
||||
if (IsExtensionSupported(OES_EGL_image_external) &&
|
||||
mRenderer != GLRenderer::AndroidEmulator) {
|
||||
return LOCAL_GL_TEXTURE_EXTERNAL;
|
||||
}
|
||||
return LOCAL_GL_TEXTURE_2D;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -69,18 +69,18 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(const SharedSurfaceDesc& desc,
|
||||
const EGLImage image)
|
||||
: SharedSurface(desc, std::move(fb)),
|
||||
mMutex("SharedSurface_EGLImage mutex"),
|
||||
mEglDisplay(GLContextEGL::Cast(desc.gl)->mEgl),
|
||||
mImage(image) {}
|
||||
|
||||
SharedSurface_EGLImage::~SharedSurface_EGLImage() {
|
||||
const auto& gle = GLContextEGL::Cast(mDesc.gl);
|
||||
const auto& egl = gle->mEgl;
|
||||
egl->fDestroyImage(mImage);
|
||||
if (auto display = mEglDisplay.lock()) {
|
||||
display->fDestroyImage(mImage);
|
||||
|
||||
if (mSync) {
|
||||
// We can't call this unless we have the ext, but we will always have
|
||||
// the ext if we have something to destroy.
|
||||
egl->fDestroySync(mSync);
|
||||
mSync = 0;
|
||||
display->fDestroySync(mSync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class EglDisplay;
|
||||
class GLLibraryEGL;
|
||||
|
||||
// -
|
||||
@@ -27,6 +28,7 @@ class GLLibraryEGL;
|
||||
class SharedSurface_EGLImage final : public SharedSurface {
|
||||
mutable Mutex mMutex MOZ_UNANNOTATED;
|
||||
EGLSync mSync = 0;
|
||||
const std::weak_ptr<EglDisplay> mEglDisplay;
|
||||
|
||||
public:
|
||||
const EGLImage mImage;
|
||||
|
||||
@@ -927,7 +927,9 @@ EGLImageTextureSource::EGLImageTextureSource(TextureSourceProvider* aProvider,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
GLenum aTarget, GLenum aWrapMode,
|
||||
gfx::IntSize aSize)
|
||||
: mImage(aImage),
|
||||
: mGL(aProvider->GetGLContext()),
|
||||
mCompositor(aProvider->AsCompositorOGL()),
|
||||
mImage(aImage),
|
||||
mFormat(aFormat),
|
||||
mTextureTarget(aTarget),
|
||||
mWrapMode(aWrapMode),
|
||||
@@ -989,9 +991,8 @@ EGLImageTextureHost::~EGLImageTextureHost() = default;
|
||||
gl::GLContext* EGLImageTextureHost::gl() const { return nullptr; }
|
||||
|
||||
gfx::SurfaceFormat EGLImageTextureHost::GetFormat() const {
|
||||
MOZ_ASSERT(mTextureSource);
|
||||
return mTextureSource ? mTextureSource->GetFormat()
|
||||
: gfx::SurfaceFormat::UNKNOWN;
|
||||
return mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
|
||||
: gfx::SurfaceFormat::R8G8B8X8;
|
||||
}
|
||||
|
||||
void EGLImageTextureHost::CreateRenderTexture(
|
||||
@@ -999,7 +1000,7 @@ void EGLImageTextureHost::CreateRenderTexture(
|
||||
MOZ_ASSERT(mExternalImageId.isSome());
|
||||
|
||||
RefPtr<wr::RenderTextureHost> texture =
|
||||
new wr::RenderEGLImageTextureHost(mImage, mSync, mSize);
|
||||
new wr::RenderEGLImageTextureHost(mImage, mSync, mSize, GetFormat());
|
||||
wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId,
|
||||
texture.forget());
|
||||
}
|
||||
@@ -1010,11 +1011,18 @@ void EGLImageTextureHost::PushResourceUpdates(
|
||||
auto method = aOp == TextureHost::ADD_IMAGE
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType = wr::ExternalImageType::TextureHandle(
|
||||
|
||||
// Prefer TextureExternal unless the backend requires TextureRect.
|
||||
TextureHost::NativeTexturePolicy policy =
|
||||
TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
|
||||
GetSize());
|
||||
auto imageType = policy == TextureHost::NativeTexturePolicy::REQUIRE
|
||||
? wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureRect)
|
||||
: wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
|
||||
gfx::SurfaceFormat format =
|
||||
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8;
|
||||
gfx::SurfaceFormat format = GetFormat();
|
||||
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
// XXX Add RGBA handling. Temporary hack to avoid crash
|
||||
@@ -1030,12 +1038,21 @@ void EGLImageTextureHost::PushDisplayItems(
|
||||
wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) {
|
||||
bool preferCompositorSurface =
|
||||
aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE);
|
||||
bool supportsExternalCompositing =
|
||||
SupportsExternalCompositing(aBuilder.GetBackendType());
|
||||
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
aBuilder.PushImage(
|
||||
aBounds, aClip, true, false, aFilter, aImageKeys[0],
|
||||
aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0],
|
||||
!(mFlags & TextureFlags::NON_PREMULTIPLIED),
|
||||
wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
|
||||
aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE));
|
||||
preferCompositorSurface, supportsExternalCompositing);
|
||||
}
|
||||
|
||||
bool EGLImageTextureHost::SupportsExternalCompositing(
|
||||
WebRenderBackend aBackend) {
|
||||
return aBackend == WebRenderBackend::SOFTWARE;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -643,6 +643,8 @@ class EGLImageTextureHost final : public TextureHost {
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
PushDisplayItemFlagSet aFlags) override;
|
||||
|
||||
bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
|
||||
|
||||
protected:
|
||||
const EGLImage mImage;
|
||||
const EGLSync mSync;
|
||||
|
||||
@@ -283,7 +283,8 @@ void RenderCompositorLayersSWGL::AttachExternalImage(
|
||||
image->AsRenderDXGIYCbCrTextureHost());
|
||||
#elif defined(ANDROID)
|
||||
MOZ_RELEASE_ASSERT(image->AsRenderAndroidHardwareBufferTextureHost() ||
|
||||
image->AsRenderAndroidSurfaceTextureHost());
|
||||
image->AsRenderAndroidSurfaceTextureHost() ||
|
||||
image->AsRenderEGLImageTextureHost());
|
||||
#endif
|
||||
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
|
||||
@@ -9,16 +9,20 @@
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "OGLShaderConfig.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
RenderEGLImageTextureHost::RenderEGLImageTextureHost(EGLImage aImage,
|
||||
EGLSync aSync,
|
||||
gfx::IntSize aSize)
|
||||
gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat)
|
||||
: mImage(aImage),
|
||||
mSync(aSync),
|
||||
mSize(aSize),
|
||||
mFormat(aFormat),
|
||||
mTextureTarget(LOCAL_GL_TEXTURE_2D),
|
||||
mTextureHandle(0) {
|
||||
MOZ_COUNT_CTOR_INHERITED(RenderEGLImageTextureHost, RenderTextureHost);
|
||||
@@ -35,8 +39,7 @@ wr::WrExternalImage RenderEGLImageTextureHost::Lock(uint8_t aChannelIndex,
|
||||
|
||||
if (mGL.get() != aGL) {
|
||||
if (mGL) {
|
||||
// This should not happen. SharedSurface_EGLImage is created only in
|
||||
// parent process.
|
||||
// This should not happen. On android, SingletonGL is used.
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected GL context");
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
@@ -47,35 +50,10 @@ wr::WrExternalImage RenderEGLImageTextureHost::Lock(uint8_t aChannelIndex,
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
|
||||
EGLint status = LOCAL_EGL_CONDITION_SATISFIED;
|
||||
if (mSync) {
|
||||
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
||||
const auto& egl = gle->mEgl;
|
||||
MOZ_ASSERT(egl->IsExtensionSupported(gl::EGLExtension::KHR_fence_sync));
|
||||
status = egl->fClientWaitSync(mSync, 0, LOCAL_EGL_FOREVER);
|
||||
// We do not need to delete sync here. It is deleted by
|
||||
// SharedSurface_EGLImage.
|
||||
mSync = 0;
|
||||
}
|
||||
|
||||
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
|
||||
MOZ_ASSERT(
|
||||
status != 0,
|
||||
"ClientWaitSync generated an error. Has mSync already been destroyed?");
|
||||
if (!WaitSync() || !CreateTextureHandle()) {
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
|
||||
if (!mTextureHandle) {
|
||||
mTextureTarget = mGL->GetPreferredEGLImageTextureTarget();
|
||||
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
|
||||
mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
|
||||
|
||||
mGL->fGenTextures(1, &mTextureHandle);
|
||||
ActivateBindAndTexParameteri(mGL, LOCAL_GL_TEXTURE0, mTextureTarget,
|
||||
mTextureHandle);
|
||||
mGL->fEGLImageTargetTexture2D(mTextureTarget, mImage);
|
||||
}
|
||||
|
||||
const auto uvs = GetUvCoords(mSize);
|
||||
return NativeTextureToWrExternalImage(
|
||||
mTextureHandle, uvs.first.x, uvs.first.y, uvs.second.x, uvs.second.y);
|
||||
@@ -83,14 +61,162 @@ wr::WrExternalImage RenderEGLImageTextureHost::Lock(uint8_t aChannelIndex,
|
||||
|
||||
void RenderEGLImageTextureHost::Unlock() {}
|
||||
|
||||
RefPtr<layers::TextureSource> RenderEGLImageTextureHost::CreateTextureSource(
|
||||
layers::TextureSourceProvider* aProvider) {
|
||||
gl::GLContext* gl = aProvider->GetGLContext();
|
||||
if (mGL.get() != gl) {
|
||||
if (mGL) {
|
||||
// This should not happen. On android, SingletonGL is used.
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected GL context");
|
||||
return nullptr;
|
||||
}
|
||||
mGL = gl;
|
||||
}
|
||||
|
||||
if (!WaitSync()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new layers::EGLImageTextureSource(
|
||||
aProvider, mImage, mFormat, gl->GetPreferredEGLImageTextureTarget(),
|
||||
LOCAL_GL_CLAMP_TO_EDGE, mSize);
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat RenderEGLImageTextureHost::GetFormat() const {
|
||||
MOZ_ASSERT(mFormat == gfx::SurfaceFormat::R8G8B8A8 ||
|
||||
mFormat == gfx::SurfaceFormat::R8G8B8X8);
|
||||
// SWGL does not support RGBA/RGBX so we must provide data in BGRA/BGRX
|
||||
// format. ReadTexImage() called by MapPlane() will ensure that data gets
|
||||
// converted correctly.
|
||||
if (mFormat == gfx::SurfaceFormat::R8G8B8A8) {
|
||||
return gfx::SurfaceFormat::B8G8R8A8;
|
||||
}
|
||||
|
||||
if (mFormat == gfx::SurfaceFormat::R8G8B8X8) {
|
||||
return gfx::SurfaceFormat::B8G8R8X8;
|
||||
}
|
||||
|
||||
gfxCriticalNoteOnce << "Unexpected color format of RenderEGLImageTextureHost";
|
||||
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
bool RenderEGLImageTextureHost::MapPlane(RenderCompositor* aCompositor,
|
||||
uint8_t aChannelIndex,
|
||||
PlaneInfo& aPlaneInfo) {
|
||||
RefPtr<gfx::DataSourceSurface> readback = ReadTexImage();
|
||||
if (!readback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gfx::DataSourceSurface::MappedSurface map;
|
||||
if (!readback->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mReadback = readback;
|
||||
aPlaneInfo.mSize = mSize;
|
||||
aPlaneInfo.mStride = map.mStride;
|
||||
aPlaneInfo.mData = map.mData;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderEGLImageTextureHost::UnmapPlanes() {
|
||||
if (mReadback) {
|
||||
mReadback->Unmap();
|
||||
mReadback = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderEGLImageTextureHost::CreateTextureHandle() {
|
||||
if (mTextureHandle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mTextureTarget = mGL->GetPreferredEGLImageTextureTarget();
|
||||
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
|
||||
mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
|
||||
|
||||
mGL->fGenTextures(1, &mTextureHandle);
|
||||
ActivateBindAndTexParameteri(mGL, LOCAL_GL_TEXTURE0, mTextureTarget,
|
||||
mTextureHandle);
|
||||
mGL->fEGLImageTargetTexture2D(mTextureTarget, mImage);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderEGLImageTextureHost::DeleteTextureHandle() {
|
||||
if (mTextureHandle) {
|
||||
if (mGL && mGL->MakeCurrent()) {
|
||||
// XXX recycle gl texture, since SharedSurface_EGLImage and
|
||||
// RenderEGLImageTextureHost is not recycled.
|
||||
mGL->fDeleteTextures(1, &mTextureHandle);
|
||||
}
|
||||
mTextureHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderEGLImageTextureHost::WaitSync() {
|
||||
bool syncSucceeded = true;
|
||||
if (mSync) {
|
||||
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
||||
const auto& egl = gle->mEgl;
|
||||
MOZ_ASSERT(egl->IsExtensionSupported(gl::EGLExtension::KHR_fence_sync));
|
||||
if (egl->IsExtensionSupported(gl::EGLExtension::KHR_wait_sync)) {
|
||||
syncSucceeded = egl->fWaitSync(mSync, 0) == LOCAL_EGL_TRUE;
|
||||
} else {
|
||||
syncSucceeded = egl->fClientWaitSync(mSync, 0, LOCAL_EGL_FOREVER) ==
|
||||
LOCAL_EGL_CONDITION_SATISFIED;
|
||||
}
|
||||
// We do not need to delete sync here. It is deleted by
|
||||
// SharedSurface_EGLImage.
|
||||
mSync = 0;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(
|
||||
syncSucceeded,
|
||||
"(Client)WaitSync generated an error. Has mSync already been destroyed?");
|
||||
return syncSucceeded;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface>
|
||||
RenderEGLImageTextureHost::ReadTexImage() {
|
||||
if (!mGL) {
|
||||
mGL = RenderThread::Get()->SingletonGL();
|
||||
if (!mGL) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WaitSync() || !CreateTextureHandle()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate resulting image surface.
|
||||
// Use GetFormat() rather than mFormat for the DataSourceSurface. eg BGRA
|
||||
// rather than RGBA, as the latter is not supported by swgl.
|
||||
// ReadTexImageHelper will take care of converting the data for us.
|
||||
const gfx::SurfaceFormat surfFormat = GetFormat();
|
||||
int32_t stride = mSize.width * BytesPerPixel(surfFormat);
|
||||
RefPtr<gfx::DataSourceSurface> surf =
|
||||
gfx::Factory::CreateDataSourceSurfaceWithStride(mSize, surfFormat,
|
||||
stride);
|
||||
if (!surf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
layers::ShaderConfigOGL config =
|
||||
layers::ShaderConfigFromTargetAndFormat(mTextureTarget, mFormat);
|
||||
int shaderConfig = config.mFeatures;
|
||||
|
||||
bool ret = mGL->ReadTexImageHelper()->ReadTexImage(
|
||||
surf, mTextureHandle, mTextureTarget, mSize, shaderConfig,
|
||||
/* aYInvert */ false);
|
||||
if (!ret) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define MOZILLA_GFX_RENDEREGLIMAGETEXTUREHOST_H
|
||||
|
||||
#include "mozilla/layers/TextureHostOGL.h"
|
||||
#include "RenderTextureHost.h"
|
||||
#include "RenderTextureHostSWGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -16,28 +16,50 @@ namespace wr {
|
||||
|
||||
// RenderEGLImageTextureHost is created only for SharedSurface_EGLImage that is
|
||||
// created in parent process.
|
||||
class RenderEGLImageTextureHost final : public RenderTextureHost {
|
||||
class RenderEGLImageTextureHost final : public RenderTextureHostSWGL {
|
||||
public:
|
||||
RenderEGLImageTextureHost(EGLImage aImage, EGLSync aSync, gfx::IntSize aSize);
|
||||
RenderEGLImageTextureHost(EGLImage aImage, EGLSync aSync, gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat);
|
||||
|
||||
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override;
|
||||
void Unlock() override;
|
||||
size_t Bytes() override {
|
||||
// XXX: we don't have a format so we can't get bpp.
|
||||
return mSize.width * mSize.height;
|
||||
return mSize.width * mSize.height * BytesPerPixel(mFormat);
|
||||
}
|
||||
|
||||
RenderEGLImageTextureHost* AsRenderEGLImageTextureHost() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
RefPtr<layers::TextureSource> CreateTextureSource(
|
||||
layers::TextureSourceProvider* aProvider) override;
|
||||
|
||||
// RenderTextureHostSWGL
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
gfx::ColorDepth GetColorDepth() const override {
|
||||
return gfx::ColorDepth::COLOR_8;
|
||||
}
|
||||
size_t GetPlaneCount() const override { return 1; };
|
||||
bool MapPlane(RenderCompositor* aCompositor, uint8_t aChannelIndex,
|
||||
PlaneInfo& aPlaneInfo) override;
|
||||
void UnmapPlanes() override;
|
||||
|
||||
private:
|
||||
virtual ~RenderEGLImageTextureHost();
|
||||
bool CreateTextureHandle();
|
||||
void DeleteTextureHandle();
|
||||
bool WaitSync();
|
||||
already_AddRefed<gfx::DataSourceSurface> ReadTexImage();
|
||||
|
||||
const EGLImage mImage;
|
||||
EGLSync mSync;
|
||||
const gfx::IntSize mSize;
|
||||
const gfx::SurfaceFormat mFormat;
|
||||
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
GLenum mTextureTarget;
|
||||
GLuint mTextureHandle;
|
||||
RefPtr<gfx::DataSourceSurface> mReadback;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
|
||||
@@ -28,6 +28,7 @@ class TextureSourceProvider;
|
||||
|
||||
namespace wr {
|
||||
|
||||
class RenderEGLImageTextureHost;
|
||||
class RenderAndroidHardwareBufferTextureHost;
|
||||
class RenderAndroidSurfaceTextureHost;
|
||||
class RenderCompositor;
|
||||
@@ -104,6 +105,10 @@ class RenderTextureHost {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual RenderEGLImageTextureHost* AsRenderEGLImageTextureHost() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual RenderAndroidHardwareBufferTextureHost*
|
||||
AsRenderAndroidHardwareBufferTextureHost() {
|
||||
return nullptr;
|
||||
|
||||
@@ -151,6 +151,14 @@ RenderTextureHostWrapper::AsRenderAndroidSurfaceTextureHost() {
|
||||
return mTextureHost->AsRenderAndroidSurfaceTextureHost();
|
||||
}
|
||||
|
||||
RenderEGLImageTextureHost*
|
||||
RenderTextureHostWrapper::AsRenderEGLImageTextureHost() {
|
||||
if (!mTextureHost) {
|
||||
return nullptr;
|
||||
}
|
||||
return mTextureHost->AsRenderEGLImageTextureHost();
|
||||
}
|
||||
|
||||
RenderTextureHostSWGL* RenderTextureHostWrapper::EnsureRenderTextureHostSWGL()
|
||||
const {
|
||||
if (!mTextureHost) {
|
||||
|
||||
@@ -45,6 +45,7 @@ class RenderTextureHostWrapper final : public RenderTextureHostSWGL {
|
||||
RenderAndroidHardwareBufferTextureHost*
|
||||
AsRenderAndroidHardwareBufferTextureHost() override;
|
||||
RenderAndroidSurfaceTextureHost* AsRenderAndroidSurfaceTextureHost() override;
|
||||
RenderEGLImageTextureHost* AsRenderEGLImageTextureHost() override;
|
||||
RenderTextureHostSWGL* AsRenderTextureHostSWGL() override;
|
||||
void SetIsSoftwareDecodedVideo() override;
|
||||
bool IsSoftwareDecodedVideo() override;
|
||||
|
||||
Reference in New Issue
Block a user