mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1813267 - Add WebRender (Software OpenGL) handling for AndroidHardwareBufferTextureHost r=gfx-reviewers,jnicol
Implementation is borrowed from RenderAndroidSurfaceTextureHost. Since Android SurfaceTexture and AndroidHardwareBuffer use same android GraphicBuffer. Differential Revision: https://phabricator.services.mozilla.com/D168764
This commit is contained in:
parent
418f826d71
commit
425786bd75
@ -612,6 +612,140 @@ bool SurfaceTextureHost::SupportsExternalCompositing(
|
||||
return aBackend == WebRenderBackend::SOFTWARE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AndroidHardwareBufferTextureSource
|
||||
|
||||
AndroidHardwareBufferTextureSource::AndroidHardwareBufferTextureSource(
|
||||
TextureSourceProvider* aProvider,
|
||||
AndroidHardwareBuffer* aAndroidHardwareBuffer, gfx::SurfaceFormat aFormat,
|
||||
GLenum aTarget, GLenum aWrapMode, gfx::IntSize aSize)
|
||||
: mGL(aProvider->GetGLContext()),
|
||||
mAndroidHardwareBuffer(aAndroidHardwareBuffer),
|
||||
mFormat(aFormat),
|
||||
mTextureTarget(aTarget),
|
||||
mWrapMode(aWrapMode),
|
||||
mSize(aSize),
|
||||
mEGLImage(EGL_NO_IMAGE),
|
||||
mTextureHandle(0) {}
|
||||
|
||||
AndroidHardwareBufferTextureSource::~AndroidHardwareBufferTextureSource() {
|
||||
DeleteTextureHandle();
|
||||
DestroyEGLImage();
|
||||
}
|
||||
|
||||
bool AndroidHardwareBufferTextureSource::EnsureEGLImage() {
|
||||
if (!mAndroidHardwareBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fenceFd = mAndroidHardwareBuffer->GetAndResetAcquireFence();
|
||||
if (fenceFd.IsValid()) {
|
||||
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
||||
const auto& egl = gle->mEgl;
|
||||
|
||||
auto rawFD = fenceFd.TakePlatformHandle();
|
||||
const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
|
||||
rawFD.get(), LOCAL_EGL_NONE};
|
||||
|
||||
EGLSync sync =
|
||||
egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
|
||||
if (sync) {
|
||||
// Release fd here, since it is owned by EGLSync
|
||||
Unused << rawFD.release();
|
||||
|
||||
if (egl->IsExtensionSupported(gl::EGLExtension::KHR_wait_sync)) {
|
||||
egl->fWaitSync(sync, 0);
|
||||
} else {
|
||||
egl->fClientWaitSync(sync, 0, LOCAL_EGL_FOREVER);
|
||||
}
|
||||
egl->fDestroySync(sync);
|
||||
} else {
|
||||
gfxCriticalNote << "Failed to create EGLSync from acquire fence fd";
|
||||
}
|
||||
}
|
||||
|
||||
if (mTextureHandle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mEGLImage) {
|
||||
// XXX add crop handling for video
|
||||
// Should only happen the first time.
|
||||
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
||||
const auto& egl = gle->mEgl;
|
||||
|
||||
const EGLint attrs[] = {
|
||||
LOCAL_EGL_IMAGE_PRESERVED,
|
||||
LOCAL_EGL_TRUE,
|
||||
LOCAL_EGL_NONE,
|
||||
LOCAL_EGL_NONE,
|
||||
};
|
||||
|
||||
EGLClientBuffer clientBuffer = egl->mLib->fGetNativeClientBufferANDROID(
|
||||
mAndroidHardwareBuffer->GetNativeBuffer());
|
||||
mEGLImage = egl->fCreateImage(
|
||||
EGL_NO_CONTEXT, LOCAL_EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs);
|
||||
}
|
||||
MOZ_ASSERT(mEGLImage);
|
||||
|
||||
mGL->fGenTextures(1, &mTextureHandle);
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, mTextureHandle);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL, LOCAL_GL_TEXTURE_WRAP_T,
|
||||
LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL, LOCAL_GL_TEXTURE_WRAP_S,
|
||||
LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mEGLImage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AndroidHardwareBufferTextureSource::DeleteTextureHandle() {
|
||||
if (!mTextureHandle) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mGL);
|
||||
mGL->fDeleteTextures(1, &mTextureHandle);
|
||||
mTextureHandle = 0;
|
||||
}
|
||||
|
||||
void AndroidHardwareBufferTextureSource::DestroyEGLImage() {
|
||||
if (!mEGLImage) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mGL);
|
||||
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
||||
const auto& egl = gle->mEgl;
|
||||
egl->fDestroyImage(mEGLImage);
|
||||
mEGLImage = EGL_NO_IMAGE;
|
||||
}
|
||||
|
||||
void AndroidHardwareBufferTextureSource::BindTexture(
|
||||
GLenum aTextureUnit, gfx::SamplingFilter aSamplingFilter) {
|
||||
MOZ_ASSERT(mAndroidHardwareBuffer);
|
||||
GLContext* gl = this->gl();
|
||||
if (!gl || !gl->MakeCurrent()) {
|
||||
NS_WARNING("Trying to bind a texture without a GLContext");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EnsureEGLImage()) {
|
||||
return;
|
||||
}
|
||||
|
||||
gl->fActiveTexture(aTextureUnit);
|
||||
gl->fBindTexture(mTextureTarget, mTextureHandle);
|
||||
|
||||
ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
|
||||
}
|
||||
|
||||
bool AndroidHardwareBufferTextureSource::IsValid() const { return !!gl(); }
|
||||
|
||||
void AndroidHardwareBufferTextureSource::DeallocateDeviceData() {
|
||||
DestroyEGLImage();
|
||||
DeleteTextureHandle();
|
||||
mAndroidHardwareBuffer = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AndroidHardwareBufferTextureHost
|
||||
|
||||
@ -632,7 +766,9 @@ AndroidHardwareBufferTextureHost::Create(
|
||||
AndroidHardwareBufferTextureHost::AndroidHardwareBufferTextureHost(
|
||||
TextureFlags aFlags, AndroidHardwareBuffer* aAndroidHardwareBuffer)
|
||||
: TextureHost(TextureHostType::AndroidHardwareBuffer, aFlags),
|
||||
mAndroidHardwareBuffer(aAndroidHardwareBuffer) {}
|
||||
mAndroidHardwareBuffer(aAndroidHardwareBuffer) {
|
||||
MOZ_ASSERT(mAndroidHardwareBuffer);
|
||||
}
|
||||
|
||||
AndroidHardwareBufferTextureHost::~AndroidHardwareBufferTextureHost() {}
|
||||
|
||||
@ -702,8 +838,16 @@ void AndroidHardwareBufferTextureHost::PushResourceUpdates(
|
||||
auto method = aOp == TextureHost::ADD_IMAGE
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType = wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
|
||||
// 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);
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
@ -729,17 +873,21 @@ void AndroidHardwareBufferTextureHost::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());
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8: {
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
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));
|
||||
aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0],
|
||||
!(mFlags & TextureFlags::NON_PREMULTIPLIED),
|
||||
wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
|
||||
preferCompositorSurface, supportsExternalCompositing);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -748,6 +896,11 @@ void AndroidHardwareBufferTextureHost::PushDisplayItems(
|
||||
}
|
||||
}
|
||||
|
||||
bool AndroidHardwareBufferTextureHost::SupportsExternalCompositing(
|
||||
WebRenderBackend aBackend) {
|
||||
return aBackend == WebRenderBackend::SOFTWARE;
|
||||
}
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -443,6 +443,53 @@ class SurfaceTextureHost : public TextureHost {
|
||||
RefPtr<SurfaceTextureSource> mTextureSource;
|
||||
};
|
||||
|
||||
class AndroidHardwareBufferTextureSource : public TextureSource,
|
||||
public TextureSourceOGL {
|
||||
public:
|
||||
AndroidHardwareBufferTextureSource(
|
||||
TextureSourceProvider* aProvider,
|
||||
AndroidHardwareBuffer* aAndroidHardwareBuffer, gfx::SurfaceFormat aFormat,
|
||||
GLenum aTarget, GLenum aWrapMode, gfx::IntSize aSize);
|
||||
|
||||
const char* Name() const override { return "SurfaceTextureSource"; }
|
||||
|
||||
TextureSourceOGL* AsSourceOGL() override { return this; }
|
||||
|
||||
void BindTexture(GLenum activetex,
|
||||
gfx::SamplingFilter aSamplingFilter) override;
|
||||
|
||||
bool IsValid() const override;
|
||||
|
||||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
GLenum GetTextureTarget() const override { return mTextureTarget; }
|
||||
|
||||
GLenum GetWrapMode() const override { return mWrapMode; }
|
||||
|
||||
void DeallocateDeviceData() override;
|
||||
|
||||
gl::GLContext* gl() const { return mGL; }
|
||||
|
||||
protected:
|
||||
virtual ~AndroidHardwareBufferTextureSource();
|
||||
|
||||
bool EnsureEGLImage();
|
||||
void DestroyEGLImage();
|
||||
void DeleteTextureHandle();
|
||||
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
RefPtr<AndroidHardwareBuffer> mAndroidHardwareBuffer;
|
||||
const gfx::SurfaceFormat mFormat;
|
||||
const GLenum mTextureTarget;
|
||||
const GLenum mWrapMode;
|
||||
const gfx::IntSize mSize;
|
||||
|
||||
EGLImage mEGLImage;
|
||||
GLuint mTextureHandle;
|
||||
};
|
||||
|
||||
class AndroidHardwareBufferTextureHost : public TextureHost {
|
||||
public:
|
||||
static already_AddRefed<AndroidHardwareBufferTextureHost> Create(
|
||||
@ -500,6 +547,8 @@ class AndroidHardwareBufferTextureHost : public TextureHost {
|
||||
return mAndroidHardwareBuffer;
|
||||
}
|
||||
|
||||
bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
|
||||
|
||||
// gecko does not need deferred deletion with WebRender
|
||||
// GPU/hardware task end could be checked by android fence.
|
||||
bool NeedsDeferredDeletion() const override { return false; }
|
||||
|
@ -7,8 +7,11 @@
|
||||
#include "RenderAndroidHardwareBufferTextureHost.h"
|
||||
|
||||
#include "mozilla/layers/AndroidHardwareBuffer.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "OGLShaderConfig.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
@ -159,5 +162,85 @@ void RenderAndroidHardwareBufferTextureHost::DestroyEGLImage() {
|
||||
mEGLImage = EGL_NO_IMAGE;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat RenderAndroidHardwareBufferTextureHost::GetFormat() const {
|
||||
MOZ_ASSERT(mAndroidHardwareBuffer->mFormat == gfx::SurfaceFormat::R8G8B8A8 ||
|
||||
mAndroidHardwareBuffer->mFormat == gfx::SurfaceFormat::R8G8B8X8);
|
||||
|
||||
if (mAndroidHardwareBuffer->mFormat == gfx::SurfaceFormat::R8G8B8A8) {
|
||||
return gfx::SurfaceFormat::B8G8R8A8;
|
||||
}
|
||||
|
||||
if (mAndroidHardwareBuffer->mFormat == gfx::SurfaceFormat::R8G8B8X8) {
|
||||
return gfx::SurfaceFormat::B8G8R8X8;
|
||||
}
|
||||
|
||||
gfxCriticalNoteOnce
|
||||
<< "Unexpected color format of RenderAndroidSurfaceTextureHost";
|
||||
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
already_AddRefed<DataSourceSurface>
|
||||
RenderAndroidHardwareBufferTextureHost::ReadTexImage() {
|
||||
if (!mGL) {
|
||||
mGL = RenderThread::Get()->SingletonGL();
|
||||
if (!mGL) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EnsureLockable()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Allocate resulting image surface */
|
||||
int32_t stride = GetSize().width * BytesPerPixel(GetFormat());
|
||||
RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurfaceWithStride(
|
||||
GetSize(), GetFormat(), stride);
|
||||
if (!surf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
layers::ShaderConfigOGL config = layers::ShaderConfigFromTargetAndFormat(
|
||||
LOCAL_GL_TEXTURE_EXTERNAL, mAndroidHardwareBuffer->mFormat);
|
||||
int shaderConfig = config.mFeatures;
|
||||
|
||||
bool ret = mGL->ReadTexImageHelper()->ReadTexImage(
|
||||
surf, mTextureHandle, LOCAL_GL_TEXTURE_EXTERNAL, GetSize(), shaderConfig,
|
||||
/* aYInvert */ false);
|
||||
if (!ret) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
bool RenderAndroidHardwareBufferTextureHost::MapPlane(
|
||||
RenderCompositor* aCompositor, uint8_t aChannelIndex,
|
||||
PlaneInfo& aPlaneInfo) {
|
||||
RefPtr<gfx::DataSourceSurface> readback = ReadTexImage();
|
||||
if (!readback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface map;
|
||||
if (!readback->Map(DataSourceSurface::MapType::READ, &map)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mReadback = readback;
|
||||
aPlaneInfo.mSize = GetSize();
|
||||
aPlaneInfo.mStride = map.mStride;
|
||||
aPlaneInfo.mData = map.mData;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderAndroidHardwareBufferTextureHost::UnmapPlanes() {
|
||||
if (mReadback) {
|
||||
mReadback->Unmap();
|
||||
mReadback = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
@ -7,8 +7,9 @@
|
||||
#ifndef MOZILLA_GFX_RenderAndroidHardwareBufferTextureHost_H
|
||||
#define MOZILLA_GFX_RenderAndroidHardwareBufferTextureHost_H
|
||||
|
||||
#include "GLContextTypes.h"
|
||||
#include "GLTypes.h"
|
||||
#include "RenderTextureHost.h"
|
||||
#include "RenderTextureHostSWGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -18,7 +19,8 @@ class AndroidHardwareBuffer;
|
||||
|
||||
namespace wr {
|
||||
|
||||
class RenderAndroidHardwareBufferTextureHost final : public RenderTextureHost {
|
||||
class RenderAndroidHardwareBufferTextureHost final
|
||||
: public RenderTextureHostSWGL {
|
||||
public:
|
||||
explicit RenderAndroidHardwareBufferTextureHost(
|
||||
layers::AndroidHardwareBuffer* aAndroidHardwareBuffer);
|
||||
@ -28,18 +30,41 @@ class RenderAndroidHardwareBufferTextureHost final : public RenderTextureHost {
|
||||
|
||||
size_t Bytes() override;
|
||||
|
||||
RenderAndroidHardwareBufferTextureHost*
|
||||
AsRenderAndroidHardwareBufferTextureHost() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
layers::AndroidHardwareBuffer* GetAndroidHardwareBuffer() {
|
||||
return mAndroidHardwareBuffer;
|
||||
}
|
||||
|
||||
gfx::IntSize GetSize() const;
|
||||
|
||||
private:
|
||||
virtual ~RenderAndroidHardwareBufferTextureHost();
|
||||
bool EnsureLockable();
|
||||
void DestroyEGLImage();
|
||||
void DeleteTextureHandle();
|
||||
gfx::IntSize GetSize() const;
|
||||
already_AddRefed<gfx::DataSourceSurface> ReadTexImage();
|
||||
|
||||
const RefPtr<layers::AndroidHardwareBuffer> mAndroidHardwareBuffer;
|
||||
EGLImage mEGLImage;
|
||||
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
EGLImage mEGLImage;
|
||||
GLuint mTextureHandle;
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> mReadback;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
|
@ -282,7 +282,8 @@ void RenderCompositorLayersSWGL::AttachExternalImage(
|
||||
MOZ_RELEASE_ASSERT(image->AsRenderDXGITextureHost() ||
|
||||
image->AsRenderDXGIYCbCrTextureHost());
|
||||
#elif defined(ANDROID)
|
||||
MOZ_RELEASE_ASSERT(image->AsRenderAndroidSurfaceTextureHost());
|
||||
MOZ_RELEASE_ASSERT(image->AsRenderAndroidHardwareBufferTextureHost() ||
|
||||
image->AsRenderAndroidSurfaceTextureHost());
|
||||
#endif
|
||||
|
||||
auto surfaceCursor = mSurfaces.find(aId);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
# include "mozilla/java/GeckoSurfaceTextureWrappers.h"
|
||||
# include "mozilla/webrender/RenderAndroidHardwareBufferTextureHost.h"
|
||||
# include "mozilla/widget/AndroidCompositorWidget.h"
|
||||
# include <android/native_window.h>
|
||||
# include <android/native_window_jni.h>
|
||||
@ -195,25 +196,47 @@ void RenderCompositorOGLSWGL::HandleExternalImage(
|
||||
LOCAL_GL_TEXTURE_EXTERNAL; // This is required by SurfaceTexture
|
||||
GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
|
||||
|
||||
auto* host = aExternalImage->AsRenderAndroidSurfaceTextureHost();
|
||||
if (auto* host = aExternalImage->AsRenderAndroidSurfaceTextureHost()) {
|
||||
host->UpdateTexImageIfNecessary();
|
||||
|
||||
host->UpdateTexImageIfNecessary();
|
||||
// We need to hold the texture source separately from the effect,
|
||||
// since the effect doesn't hold a strong reference.
|
||||
RefPtr<SurfaceTextureSource> layer = new SurfaceTextureSource(
|
||||
(TextureSourceProvider*)mCompositor, host->mSurfTex, host->mFormat,
|
||||
target, wrapMode, host->mSize, host->mTransformOverride);
|
||||
RefPtr<TexturedEffect> texturedEffect =
|
||||
CreateTexturedEffect(host->mFormat, layer, aFrameSurface.mFilter,
|
||||
/* isAlphaPremultiplied */ true);
|
||||
|
||||
// We need to hold the texture source separately from the effect,
|
||||
// since the effect doesn't hold a strong reference.
|
||||
RefPtr<SurfaceTextureSource> layer = new SurfaceTextureSource(
|
||||
(TextureSourceProvider*)mCompositor, host->mSurfTex, host->mFormat,
|
||||
target, wrapMode, host->mSize, host->mTransformOverride);
|
||||
RefPtr<TexturedEffect> texturedEffect =
|
||||
CreateTexturedEffect(host->mFormat, layer, aFrameSurface.mFilter,
|
||||
/* isAlphaPremultiplied */ true);
|
||||
gfx::Rect drawRect(0, 0, host->mSize.width, host->mSize.height);
|
||||
|
||||
gfx::Rect drawRect(0, 0, host->mSize.width, host->mSize.height);
|
||||
EffectChain effect;
|
||||
effect.mPrimaryEffect = texturedEffect;
|
||||
mCompositor->DrawQuad(drawRect, aFrameSurface.mClipRect, effect, 1.0,
|
||||
aFrameSurface.mTransform, drawRect);
|
||||
} else if (auto* host =
|
||||
aExternalImage->AsRenderAndroidHardwareBufferTextureHost()) {
|
||||
// We need to hold the texture source separately from the effect,
|
||||
// since the effect doesn't hold a strong reference.
|
||||
RefPtr<AndroidHardwareBufferTextureSource> layer =
|
||||
new AndroidHardwareBufferTextureSource(
|
||||
(TextureSourceProvider*)mCompositor,
|
||||
host->GetAndroidHardwareBuffer(),
|
||||
host->GetAndroidHardwareBuffer()->mFormat, target, wrapMode,
|
||||
host->GetSize());
|
||||
RefPtr<TexturedEffect> texturedEffect = CreateTexturedEffect(
|
||||
host->GetAndroidHardwareBuffer()->mFormat, layer, aFrameSurface.mFilter,
|
||||
/* isAlphaPremultiplied */ true);
|
||||
|
||||
EffectChain effect;
|
||||
effect.mPrimaryEffect = texturedEffect;
|
||||
mCompositor->DrawQuad(drawRect, aFrameSurface.mClipRect, effect, 1.0,
|
||||
aFrameSurface.mTransform, drawRect);
|
||||
gfx::Rect drawRect(0, 0, host->GetSize().width, host->GetSize().height);
|
||||
|
||||
EffectChain effect;
|
||||
effect.mPrimaryEffect = texturedEffect;
|
||||
mCompositor->DrawQuad(drawRect, aFrameSurface.mClipRect, effect, 1.0,
|
||||
aFrameSurface.mTransform, drawRect);
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ class GLContext;
|
||||
|
||||
namespace wr {
|
||||
|
||||
class RenderAndroidHardwareBufferTextureHost;
|
||||
class RenderAndroidSurfaceTextureHost;
|
||||
class RenderCompositor;
|
||||
class RenderDXGITextureHost;
|
||||
@ -86,6 +87,11 @@ class RenderTextureHost {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual RenderAndroidHardwareBufferTextureHost*
|
||||
AsRenderAndroidHardwareBufferTextureHost() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual RenderAndroidSurfaceTextureHost* AsRenderAndroidSurfaceTextureHost() {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -178,6 +178,14 @@ RenderTextureHostSWGL* RenderTextureHostWrapper::AsRenderTextureHostSWGL() {
|
||||
return mTextureHost->AsRenderTextureHostSWGL();
|
||||
}
|
||||
|
||||
RenderAndroidHardwareBufferTextureHost*
|
||||
RenderTextureHostWrapper::AsRenderAndroidHardwareBufferTextureHost() {
|
||||
if (!mTextureHost) {
|
||||
return nullptr;
|
||||
}
|
||||
return mTextureHost->AsRenderAndroidHardwareBufferTextureHost();
|
||||
}
|
||||
|
||||
RenderAndroidSurfaceTextureHost*
|
||||
RenderTextureHostWrapper::AsRenderAndroidSurfaceTextureHost() {
|
||||
if (!mTextureHost) {
|
||||
|
@ -43,6 +43,8 @@ class RenderTextureHostWrapper final : public RenderTextureHostSWGL {
|
||||
RenderDXGITextureHost* AsRenderDXGITextureHost() override;
|
||||
RenderDXGIYCbCrTextureHost* AsRenderDXGIYCbCrTextureHost() override;
|
||||
RenderDcompSurfaceTextureHost* AsRenderDcompSurfaceTextureHost() override;
|
||||
RenderAndroidHardwareBufferTextureHost*
|
||||
AsRenderAndroidHardwareBufferTextureHost() override;
|
||||
RenderAndroidSurfaceTextureHost* AsRenderAndroidSurfaceTextureHost() override;
|
||||
RenderTextureHostSWGL* AsRenderTextureHostSWGL() override;
|
||||
bool IsWrappingAsyncRemoteTexture() override;
|
||||
|
Loading…
Reference in New Issue
Block a user