Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1532201 - Enable SurfaceFactory_EGLImage usage with WebRender r=n…
Browse files Browse the repository at this point in the history
  • Loading branch information
sotaro committed Apr 2, 2019
1 parent ef4d36f commit 4be36ac
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 3 deletions.
4 changes: 1 addition & 3 deletions gfx/gl/GLScreenBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
39 changes: 39 additions & 0 deletions gfx/layers/opengl/TextureHostOGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -817,6 +818,44 @@ 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;

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);
}

void EGLImageTextureHost::PushDisplayItems(
wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
const Range<wr::ImageKey>& aImageKeys) {
MOZ_ASSERT(aImageKeys.length() == 1);
aBuilder.PushImage(aBounds, aClip, true, aFilter, aImageKeys[0],
!(mFlags & TextureFlags::NON_PREMULTIPLIED));
}

//

GLTextureHost::GLTextureHost(TextureFlags aFlags, GLuint aTextureHandle,
Expand Down
14 changes: 14 additions & 0 deletions gfx/layers/opengl/TextureHostOGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
109 changes: 109 additions & 0 deletions gfx/webrender_bindings/RenderEGLImageTextureHost.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 46 additions & 0 deletions gfx/webrender_bindings/RenderEGLImageTextureHost.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions gfx/webrender_bindings/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ EXPORTS.mozilla.webrender += [
'RenderBufferTextureHost.h',
'RenderCompositor.h',
'RenderCompositorOGL.h',
'RenderEGLImageTextureHost.h',
'RendererOGL.h',
'RendererScreenshotGrabber.h',
'RenderSharedSurfaceTextureHost.h',
Expand All @@ -28,6 +29,7 @@ UNIFIED_SOURCES += [
'RenderBufferTextureHost.cpp',
'RenderCompositor.cpp',
'RenderCompositorOGL.cpp',
'RenderEGLImageTextureHost.cpp',
'RendererOGL.cpp',
'RendererScreenshotGrabber.cpp',
'RenderSharedSurfaceTextureHost.cpp',
Expand Down

0 comments on commit 4be36ac

Please sign in to comment.