mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1532201 - Enable SurfaceFactory_EGLImage usage with WebRender r=nical
Differential Revision: https://phabricator.services.mozilla.com/D24668 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
cbdc91e01d
commit
572a63549a
@ -88,9 +88,7 @@ UniquePtr<SurfaceFactory> GLScreenBuffer::CreateFactory(
|
||||
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel,
|
||||
mFlags);
|
||||
#elif defined(MOZ_WIDGET_ANDROID)
|
||||
// XXX WebRender does not support SurfaceFactory_EGLImage usage.
|
||||
if (XRE_IsParentProcess() && !gfxPrefs::WebGLSurfaceTextureEnabled() &&
|
||||
backend != layers::LayersBackend::LAYERS_WR) {
|
||||
if (XRE_IsParentProcess() && !gfxPrefs::WebGLSurfaceTextureEnabled()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
|
||||
} else {
|
||||
factory =
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/gfx/Logging.h" // for gfxCriticalError
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/webrender/RenderEGLImageTextureHost.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "nsRegion.h" // for nsIntRegion
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
@ -817,6 +818,60 @@ gfx::SurfaceFormat EGLImageTextureHost::GetFormat() const {
|
||||
: gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
void EGLImageTextureHost::CreateRenderTexture(
|
||||
const wr::ExternalImageId& aExternalImageId) {
|
||||
RefPtr<wr::RenderTextureHost> texture =
|
||||
new wr::RenderEGLImageTextureHost(mImage, mSync, mSize);
|
||||
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId),
|
||||
texture.forget());
|
||||
}
|
||||
|
||||
void EGLImageTextureHost::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 bufferType = wr::WrExternalImageBufferType::TextureExternalHandle;
|
||||
|
||||
gfx::SurfaceFormat format =
|
||||
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8;
|
||||
|
||||
switch (format) {
|
||||
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 formatTmp = format == gfx::SurfaceFormat::R8G8B8A8
|
||||
? gfx::SurfaceFormat::B8G8R8A8
|
||||
: gfx::SurfaceFormat::B8G8R8X8;
|
||||
wr::ImageDescriptor descriptor(GetSize(), formatTmp);
|
||||
(aResources.*method)(aImageKeys[0], descriptor, aExtID, bufferType, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EGLImageTextureHost::PushDisplayItems(
|
||||
wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) {
|
||||
gfx::SurfaceFormat format =
|
||||
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8;
|
||||
|
||||
switch (format) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::R8G8B8A8: {
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
aBuilder.PushImage(aBounds, aClip, true, aFilter, aImageKeys[0],
|
||||
!(mFlags & TextureFlags::NON_PREMULTIPLIED));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
GLTextureHost::GLTextureHost(TextureFlags aFlags, GLuint aTextureHandle,
|
||||
|
@ -545,6 +545,20 @@ class EGLImageTextureHost final : public TextureHost {
|
||||
|
||||
virtual const char* Name() override { return "EGLImageTextureHost"; }
|
||||
|
||||
virtual void CreateRenderTexture(
|
||||
const wr::ExternalImageId& aExternalImageId) override;
|
||||
|
||||
virtual void PushResourceUpdates(wr::TransactionBuilder& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) override;
|
||||
|
||||
protected:
|
||||
const EGLImage mImage;
|
||||
const EGLSync mSync;
|
||||
|
109
gfx/webrender_bindings/RenderEGLImageTextureHost.cpp
Normal file
109
gfx/webrender_bindings/RenderEGLImageTextureHost.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*- 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 "RenderEGLImageTextureHost.h"
|
||||
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
RenderEGLImageTextureHost::RenderEGLImageTextureHost(EGLImage aImage,
|
||||
EGLSync aSync,
|
||||
gfx::IntSize aSize)
|
||||
: mImage(aImage),
|
||||
mSync(aSync),
|
||||
mSize(aSize),
|
||||
mTextureTarget(LOCAL_GL_TEXTURE_2D),
|
||||
mTextureHandle(0) {
|
||||
MOZ_COUNT_CTOR_INHERITED(RenderEGLImageTextureHost, RenderTextureHostOGL);
|
||||
}
|
||||
|
||||
RenderEGLImageTextureHost::~RenderEGLImageTextureHost() {
|
||||
MOZ_COUNT_DTOR_INHERITED(RenderEGLImageTextureHost, RenderTextureHostOGL);
|
||||
DeleteTextureHandle();
|
||||
}
|
||||
|
||||
GLuint RenderEGLImageTextureHost::GetGLHandle(uint8_t aChannelIndex) const {
|
||||
return mTextureHandle;
|
||||
}
|
||||
|
||||
gfx::IntSize RenderEGLImageTextureHost::GetSize(uint8_t aChannelIndex) const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
wr::WrExternalImage RenderEGLImageTextureHost::Lock(
|
||||
uint8_t aChannelIndex, gl::GLContext* aGL, wr::ImageRendering aRendering) {
|
||||
MOZ_ASSERT(aChannelIndex == 0);
|
||||
|
||||
if (mGL.get() != aGL) {
|
||||
if (mGL) {
|
||||
// This should not happen. SharedSurface_EGLImage is created only in
|
||||
// parent process.
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected GL context");
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
mGL = aGL;
|
||||
}
|
||||
|
||||
if (!mImage || !mGL || !mGL->MakeCurrent()) {
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
|
||||
EGLint status = LOCAL_EGL_CONDITION_SATISFIED;
|
||||
if (mSync) {
|
||||
auto* egl = gl::GLLibraryEGL::Get();
|
||||
MOZ_ASSERT(egl->IsExtensionSupported(gl::GLLibraryEGL::KHR_fence_sync));
|
||||
status = egl->fClientWaitSync(egl->Display(), 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?");
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
|
||||
if (!mTextureHandle) {
|
||||
mTextureTarget = mGL->GetPreferredEGLImageTextureTarget();
|
||||
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
|
||||
mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
|
||||
|
||||
mGL->fGenTextures(1, &mTextureHandle);
|
||||
// Cache rendering filter.
|
||||
mCachedRendering = aRendering;
|
||||
ActivateBindAndTexParameteri(mGL, LOCAL_GL_TEXTURE0, mTextureTarget,
|
||||
mTextureHandle, aRendering);
|
||||
mGL->fEGLImageTargetTexture2D(mTextureTarget, mImage);
|
||||
} else if (IsFilterUpdateNecessary(aRendering)) {
|
||||
// Cache new rendering filter.
|
||||
mCachedRendering = aRendering;
|
||||
ActivateBindAndTexParameteri(mGL, LOCAL_GL_TEXTURE0, mTextureTarget,
|
||||
mTextureHandle, aRendering);
|
||||
}
|
||||
|
||||
return NativeTextureToWrExternalImage(mTextureHandle, 0, 0, mSize.width,
|
||||
mSize.height);
|
||||
}
|
||||
|
||||
void RenderEGLImageTextureHost::Unlock() {}
|
||||
|
||||
void RenderEGLImageTextureHost::DeleteTextureHandle() {
|
||||
if (mTextureHandle) {
|
||||
// XXX recycle gl texture, since SharedSurface_EGLImage and
|
||||
// RenderEGLImageTextureHost is not recycled.
|
||||
mGL->fDeleteTextures(1, &mTextureHandle);
|
||||
mTextureHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
46
gfx/webrender_bindings/RenderEGLImageTextureHost.h
Normal file
46
gfx/webrender_bindings/RenderEGLImageTextureHost.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* -*- 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_RENDEREGLIMAGETEXTUREHOSTOGL_H
|
||||
#define MOZILLA_GFX_RENDEREGLIMAGETEXTUREHOSTOGL_H
|
||||
|
||||
#include "mozilla/layers/TextureHostOGL.h"
|
||||
#include "RenderTextureHostOGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace wr {
|
||||
|
||||
// RenderEGLImageTextureHost is created only for SharedSurface_EGLImage that is
|
||||
// created in parent process.
|
||||
class RenderEGLImageTextureHost final : public RenderTextureHostOGL {
|
||||
public:
|
||||
RenderEGLImageTextureHost(EGLImage aImage, EGLSync aSync, gfx::IntSize aSize);
|
||||
|
||||
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL,
|
||||
wr::ImageRendering aRendering) override;
|
||||
void Unlock() override;
|
||||
|
||||
virtual gfx::IntSize GetSize(uint8_t aChannelIndex) const override;
|
||||
virtual GLuint GetGLHandle(uint8_t aChannelIndex) const override;
|
||||
|
||||
private:
|
||||
virtual ~RenderEGLImageTextureHost();
|
||||
void DeleteTextureHandle();
|
||||
|
||||
const EGLImage mImage;
|
||||
EGLSync mSync;
|
||||
const gfx::IntSize mSize;
|
||||
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
GLenum mTextureTarget;
|
||||
GLuint mTextureHandle;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_RENDEREGLIMAGETEXTUREHOSTOGL_H
|
@ -11,6 +11,7 @@ EXPORTS.mozilla.webrender += [
|
||||
'RenderBufferTextureHost.h',
|
||||
'RenderCompositor.h',
|
||||
'RenderCompositorOGL.h',
|
||||
'RenderEGLImageTextureHost.h',
|
||||
'RendererOGL.h',
|
||||
'RendererScreenshotGrabber.h',
|
||||
'RenderSharedSurfaceTextureHost.h',
|
||||
@ -28,6 +29,7 @@ UNIFIED_SOURCES += [
|
||||
'RenderBufferTextureHost.cpp',
|
||||
'RenderCompositor.cpp',
|
||||
'RenderCompositorOGL.cpp',
|
||||
'RenderEGLImageTextureHost.cpp',
|
||||
'RendererOGL.cpp',
|
||||
'RendererScreenshotGrabber.cpp',
|
||||
'RenderSharedSurfaceTextureHost.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user