Bug 1578380 - [Wayland] Implement WaylandDMABUFTextureHostOGL, r=sotaro

WaylandDMABufSurface is used as a backend for WaylandDMABUFTextureHostOGL.
Pixel data of WaylandDMABufSurface are located at GPU memory and are
binded from WaylandDMABUFTextureClientOGL.

WaylandDMABufSurface can be binded as EGLImage so EGLImageTextureSource is used.

Depends on D46836

Differential Revision: https://phabricator.services.mozilla.com/D46837

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Martin Stransky 2019-09-24 09:09:28 +00:00
Родитель 491e19bd05
Коммит 204c7a601e
2 изменённых файлов: 214 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,138 @@
/* -*- 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 "WaylandDMABUFTextureHostOGL.h"
#include "mozilla/widget/WaylandDMABufSurface.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "GLContextEGL.h"
namespace mozilla {
namespace layers {
WaylandDMABUFTextureHostOGL::WaylandDMABUFTextureHostOGL(
TextureFlags aFlags, const SurfaceDescriptor& aDesc)
: TextureHost(aFlags) {
MOZ_COUNT_CTOR(WaylandDMABUFTextureHostOGL);
mSurface = WaylandDMABufSurface::CreateDMABufSurface(
aDesc.get_SurfaceDescriptorDMABuf());
}
WaylandDMABUFTextureHostOGL::~WaylandDMABUFTextureHostOGL() {
MOZ_COUNT_DTOR(WaylandDMABUFTextureHostOGL);
if (mProvider) {
DeallocateDeviceData();
}
}
bool WaylandDMABUFTextureHostOGL::Lock() {
if (!gl() || !gl()->MakeCurrent() || !mSurface) {
return false;
}
if (!mTextureSource && mSurface->CreateEGLImage(gl())) {
auto format = mSurface->HasAlpha() ? gfx::SurfaceFormat::R8G8B8A8
: gfx::SurfaceFormat::R8G8B8X8;
mTextureSource = new EGLImageTextureSource(
mProvider, mSurface->GetEGLImage(), format, LOCAL_GL_TEXTURE_EXTERNAL,
LOCAL_GL_CLAMP_TO_EDGE,
gfx::IntSize(mSurface->GetWidth(), mSurface->GetHeight()));
}
return true;
}
void WaylandDMABUFTextureHostOGL::Unlock() {}
void WaylandDMABUFTextureHostOGL::DeallocateDeviceData() {
mTextureSource = nullptr;
if (mSurface) {
mSurface->ReleaseEGLImage();
}
}
void WaylandDMABUFTextureHostOGL::SetTextureSourceProvider(
TextureSourceProvider* aProvider) {
if (!aProvider || !aProvider->GetGLContext()) {
DeallocateDeviceData();
mProvider = nullptr;
return;
}
if (mProvider != aProvider) {
DeallocateDeviceData();
}
mProvider = aProvider;
if (mTextureSource) {
mTextureSource->SetTextureSourceProvider(aProvider);
}
}
gfx::SurfaceFormat WaylandDMABUFTextureHostOGL::GetFormat() const {
MOZ_ASSERT(mTextureSource);
return mTextureSource ? mTextureSource->GetFormat()
: gfx::SurfaceFormat::UNKNOWN;
}
gfx::IntSize WaylandDMABUFTextureHostOGL::GetSize() const {
if (!mSurface) {
return gfx::IntSize();
}
return gfx::IntSize(mSurface->GetWidth(), mSurface->GetHeight());
}
gl::GLContext* WaylandDMABUFTextureHostOGL::gl() const {
return mProvider ? mProvider->GetGLContext() : nullptr;
}
void WaylandDMABUFTextureHostOGL::CreateRenderTexture(
const wr::ExternalImageId& aExternalImageId) {
/* TODO
RefPtr<wr::RenderTextureHost> texture =
new wr::RenderWaylandDMABUFTextureHostOGL(mImage, mSync, mSize);
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId),
texture.forget());
*/
}
void WaylandDMABUFTextureHostOGL::PushResourceUpdates(
wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) {
MOZ_ASSERT(mSurface);
auto method = aOp == TextureHost::ADD_IMAGE
? &wr::TransactionBuilder::AddExternalImage
: &wr::TransactionBuilder::UpdateExternalImage;
auto imageType =
wr::ExternalImageType::TextureHandle(wr::TextureTarget::External);
gfx::SurfaceFormat format = mSurface->HasAlpha()
? 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, imageType, 0);
}
void WaylandDMABUFTextureHostOGL::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));
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,76 @@
/* -*- 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_WAYLANDDMABUFTEXTUREHOSTOGL_H
#define MOZILLA_GFX_WAYLANDDMABUFTEXTUREHOSTOGL_H
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/CompositorOGL.h"
#include "mozilla/layers/TextureHostOGL.h"
class WaylandDMABufSurface;
namespace mozilla {
namespace layers {
/**
* A TextureHost for shared class WaylandDMABufSurface;
*/
class WaylandDMABUFTextureHostOGL : public TextureHost {
public:
WaylandDMABUFTextureHostOGL(TextureFlags aFlags,
const SurfaceDescriptor& aDesc);
virtual ~WaylandDMABUFTextureHostOGL();
void DeallocateDeviceData() override;
void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
bool Lock() override;
void Unlock() override;
gfx::SurfaceFormat GetFormat() const override;
bool BindTextureSource(CompositableTextureSourceRef& aTexture) override {
aTexture = mTextureSource;
return !!aTexture;
}
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
gl::GLContext* gl() const;
gfx::IntSize GetSize() const override;
#ifdef MOZ_LAYERS_HAVE_LOG
const char* Name() override { return "WaylandDMABUFTextureHostOGL"; }
#endif
void CreateRenderTexture(
const wr::ExternalImageId& aExternalImageId) 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) override;
protected:
RefPtr<EGLImageTextureSource> mTextureSource;
RefPtr<WaylandDMABufSurface> mSurface;
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_WAYLANDDMABUFTEXTUREHOSTOGL_H