Bug 1649122 - Add basic AHardwareBuffer support to WebRender on android r=jrmuizel
android fence is not supported yet. Differential Revision: https://phabricator.services.mozilla.com/D82317
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
# include "mozilla/layers/AndroidHardwareBuffer.h"
|
# include "mozilla/layers/AndroidHardwareBuffer.h"
|
||||||
|
# include "mozilla/webrender/RenderAndroidHardwareBufferTextureHost.h"
|
||||||
# include "mozilla/webrender/RenderAndroidSurfaceTextureHostOGL.h"
|
# include "mozilla/webrender/RenderAndroidSurfaceTextureHostOGL.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -896,6 +897,70 @@ void AndroidHardwareBufferTextureHost::DeallocateDeviceData() {
|
|||||||
DestroyEGLImage();
|
DestroyEGLImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidHardwareBufferTextureHost::CreateRenderTexture(
|
||||||
|
const wr::ExternalImageId& aExternalImageId) {
|
||||||
|
RefPtr<wr::RenderTextureHost> texture =
|
||||||
|
new wr::RenderAndroidHardwareBufferTextureHost(mAndroidHardwareBuffer);
|
||||||
|
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId),
|
||||||
|
texture.forget());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AndroidHardwareBufferTextureHost::NumSubTextures() {
|
||||||
|
return mAndroidHardwareBuffer ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidHardwareBufferTextureHost::PushResourceUpdates(
|
||||||
|
wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
|
||||||
|
const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) {
|
||||||
|
auto method = aOp == TextureHost::ADD_IMAGE
|
||||||
|
? &wr::TransactionBuilder::AddExternalImage
|
||||||
|
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||||
|
auto imageType =
|
||||||
|
wr::ExternalImageType::TextureHandle(wr::TextureTarget::External);
|
||||||
|
|
||||||
|
switch (GetFormat()) {
|
||||||
|
case gfx::SurfaceFormat::R8G8B8X8:
|
||||||
|
case gfx::SurfaceFormat::R8G8B8A8: {
|
||||||
|
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||||
|
|
||||||
|
// XXX Add RGBA handling. Temporary hack to avoid crash
|
||||||
|
// With BGRA format setting, rendering works without problem.
|
||||||
|
auto format = GetFormat() == gfx::SurfaceFormat::R8G8B8A8
|
||||||
|
? gfx::SurfaceFormat::B8G8R8A8
|
||||||
|
: gfx::SurfaceFormat::B8G8R8X8;
|
||||||
|
wr::ImageDescriptor descriptor(GetSize(), format);
|
||||||
|
(aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidHardwareBufferTextureHost::PushDisplayItems(
|
||||||
|
wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
|
||||||
|
const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
|
||||||
|
const Range<wr::ImageKey>& aImageKeys,
|
||||||
|
const bool aPreferCompositorSurface) {
|
||||||
|
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, aFilter, aImageKeys[0],
|
||||||
|
!(mFlags & TextureFlags::NON_PREMULTIPLIED),
|
||||||
|
wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
aPreferCompositorSurface);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // MOZ_WIDGET_ANDROID
|
#endif // MOZ_WIDGET_ANDROID
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -497,6 +497,22 @@ class AndroidHardwareBufferTextureHost : public TextureHost {
|
|||||||
|
|
||||||
const char* Name() override { return "AndroidHardwareBufferTextureHost"; }
|
const char* Name() override { return "AndroidHardwareBufferTextureHost"; }
|
||||||
|
|
||||||
|
void CreateRenderTexture(
|
||||||
|
const wr::ExternalImageId& aExternalImageId) override;
|
||||||
|
|
||||||
|
uint32_t NumSubTextures() override;
|
||||||
|
|
||||||
|
void PushResourceUpdates(wr::TransactionBuilder& aResources,
|
||||||
|
ResourceUpdateOp aOp,
|
||||||
|
const Range<wr::ImageKey>& aImageKeys,
|
||||||
|
const wr::ExternalImageId& aExtID) override;
|
||||||
|
|
||||||
|
void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||||
|
const wr::LayoutRect& aBounds,
|
||||||
|
const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
|
||||||
|
const Range<wr::ImageKey>& aImageKeys,
|
||||||
|
const bool aPreferCompositorSurface) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DestroyEGLImage();
|
void DestroyEGLImage();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "RenderAndroidHardwareBufferTextureHost.h"
|
||||||
|
|
||||||
|
#include "mozilla/layers/AndroidHardwareBuffer.h"
|
||||||
|
#include "GLContextEGL.h"
|
||||||
|
#include "GLLibraryEGL.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace wr {
|
||||||
|
|
||||||
|
RenderAndroidHardwareBufferTextureHost::RenderAndroidHardwareBufferTextureHost(
|
||||||
|
layers::AndroidHardwareBuffer* aAndroidHardwareBuffer)
|
||||||
|
: mAndroidHardwareBuffer(aAndroidHardwareBuffer),
|
||||||
|
mEGLImage(EGL_NO_IMAGE),
|
||||||
|
mTextureHandle(0) {
|
||||||
|
MOZ_ASSERT(mAndroidHardwareBuffer);
|
||||||
|
MOZ_COUNT_CTOR_INHERITED(RenderAndroidHardwareBufferTextureHost,
|
||||||
|
RenderTextureHostOGL);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderAndroidHardwareBufferTextureHost::
|
||||||
|
~RenderAndroidHardwareBufferTextureHost() {
|
||||||
|
MOZ_COUNT_DTOR_INHERITED(RenderAndroidHardwareBufferTextureHost,
|
||||||
|
RenderTextureHostOGL);
|
||||||
|
DeleteTextureHandle();
|
||||||
|
DestroyEGLImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint RenderAndroidHardwareBufferTextureHost::GetGLHandle(
|
||||||
|
uint8_t aChannelIndex) const {
|
||||||
|
return mTextureHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::IntSize RenderAndroidHardwareBufferTextureHost::GetSize(
|
||||||
|
uint8_t aChannelIndex) const {
|
||||||
|
return GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::IntSize RenderAndroidHardwareBufferTextureHost::GetSize() const {
|
||||||
|
if (mAndroidHardwareBuffer) {
|
||||||
|
return mAndroidHardwareBuffer->mSize;
|
||||||
|
}
|
||||||
|
return gfx::IntSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderAndroidHardwareBufferTextureHost::EnsureLockable(
|
||||||
|
wr::ImageRendering aRendering) {
|
||||||
|
if (!mAndroidHardwareBuffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTextureHandle) {
|
||||||
|
// Update filter if filter was changed.
|
||||||
|
if (IsFilterUpdateNecessary(aRendering)) {
|
||||||
|
ActivateBindAndTexParameteri(mGL, LOCAL_GL_TEXTURE0,
|
||||||
|
LOCAL_GL_TEXTURE_EXTERNAL_OES,
|
||||||
|
mTextureHandle, aRendering);
|
||||||
|
// Cache new rendering filter.
|
||||||
|
mCachedRendering = aRendering;
|
||||||
|
}
|
||||||
|
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->fGetNativeClientBufferANDROID(
|
||||||
|
mAndroidHardwareBuffer->GetNativeBuffer());
|
||||||
|
mEGLImage =
|
||||||
|
egl->fCreateImage(egl->Display(), 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);
|
||||||
|
|
||||||
|
ActivateBindAndTexParameteri(mGL, LOCAL_GL_TEXTURE0,
|
||||||
|
LOCAL_GL_TEXTURE_EXTERNAL_OES, mTextureHandle,
|
||||||
|
aRendering);
|
||||||
|
// Cache rendering filter.
|
||||||
|
mCachedRendering = aRendering;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
wr::WrExternalImage RenderAndroidHardwareBufferTextureHost::Lock(
|
||||||
|
uint8_t aChannelIndex, gl::GLContext* aGL, wr::ImageRendering aRendering) {
|
||||||
|
MOZ_ASSERT(aChannelIndex == 0);
|
||||||
|
|
||||||
|
if (mGL.get() != aGL) {
|
||||||
|
if (mGL) {
|
||||||
|
// This should not happen.
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Unexpected GL context");
|
||||||
|
return InvalidToWrExternalImage();
|
||||||
|
}
|
||||||
|
mGL = aGL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mGL || !mGL->MakeCurrent()) {
|
||||||
|
return InvalidToWrExternalImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EnsureLockable(aRendering)) {
|
||||||
|
return InvalidToWrExternalImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX Add android Fence handling
|
||||||
|
|
||||||
|
return NativeTextureToWrExternalImage(mTextureHandle, 0, 0, GetSize().width,
|
||||||
|
GetSize().height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderAndroidHardwareBufferTextureHost::Unlock() {}
|
||||||
|
|
||||||
|
void RenderAndroidHardwareBufferTextureHost::DeleteTextureHandle() {
|
||||||
|
if (!mTextureHandle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(mGL);
|
||||||
|
mGL->fDeleteTextures(1, &mTextureHandle);
|
||||||
|
mTextureHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderAndroidHardwareBufferTextureHost::DestroyEGLImage() {
|
||||||
|
if (!mEGLImage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(mGL);
|
||||||
|
const auto& gle = gl::GLContextEGL::Cast(mGL);
|
||||||
|
const auto& egl = gle->mEgl;
|
||||||
|
egl->fDestroyImage(egl->Display(), mEGLImage);
|
||||||
|
mEGLImage = EGL_NO_IMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace wr
|
||||||
|
} // namespace mozilla
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef MOZILLA_GFX_RenderAndroidHardwareBufferTextureHost_H
|
||||||
|
#define MOZILLA_GFX_RenderAndroidHardwareBufferTextureHost_H
|
||||||
|
|
||||||
|
#include "GLTypes.h"
|
||||||
|
#include "RenderTextureHostOGL.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
namespace layers {
|
||||||
|
class AndroidHardwareBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace wr {
|
||||||
|
|
||||||
|
class RenderAndroidHardwareBufferTextureHost final
|
||||||
|
: public RenderTextureHostOGL {
|
||||||
|
public:
|
||||||
|
explicit RenderAndroidHardwareBufferTextureHost(
|
||||||
|
layers::AndroidHardwareBuffer* aAndroidHardwareBuffer);
|
||||||
|
|
||||||
|
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL,
|
||||||
|
wr::ImageRendering aRendering) override;
|
||||||
|
void Unlock() override;
|
||||||
|
|
||||||
|
gfx::IntSize GetSize(uint8_t aChannelIndex) const override;
|
||||||
|
GLuint GetGLHandle(uint8_t aChannelIndex) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual ~RenderAndroidHardwareBufferTextureHost();
|
||||||
|
bool EnsureLockable(wr::ImageRendering aRendering);
|
||||||
|
void DestroyEGLImage();
|
||||||
|
void DeleteTextureHandle();
|
||||||
|
gfx::IntSize GetSize() const;
|
||||||
|
|
||||||
|
const RefPtr<layers::AndroidHardwareBuffer> mAndroidHardwareBuffer;
|
||||||
|
EGLImage mEGLImage;
|
||||||
|
|
||||||
|
RefPtr<gl::GLContext> mGL;
|
||||||
|
GLuint mTextureHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace wr
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // MOZILLA_GFX_RenderAndroidHardwareBufferTextureHost_H
|
||||||
@@ -57,10 +57,12 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
|||||||
|
|
||||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||||
EXPORTS.mozilla.webrender += [
|
EXPORTS.mozilla.webrender += [
|
||||||
|
'RenderAndroidHardwareBufferTextureHost.h',
|
||||||
'RenderAndroidSurfaceTextureHostOGL.h',
|
'RenderAndroidSurfaceTextureHostOGL.h',
|
||||||
'RenderCompositorEGL.h',
|
'RenderCompositorEGL.h',
|
||||||
]
|
]
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
|
'RenderAndroidHardwareBufferTextureHost.cpp',
|
||||||
'RenderAndroidSurfaceTextureHostOGL.cpp',
|
'RenderAndroidSurfaceTextureHostOGL.cpp',
|
||||||
'RenderCompositorEGL.cpp',
|
'RenderCompositorEGL.cpp',
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user