1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DMABUFTextureHostOGL.h"
8 #include "mozilla/widget/DMABufSurface.h"
9 #include "mozilla/webrender/RenderDMABUFTextureHost.h"
10 #include "mozilla/webrender/RenderThread.h"
11 #include "mozilla/webrender/WebRenderAPI.h"
12 #include "GLContextEGL.h"
14 namespace mozilla::layers
{
16 DMABUFTextureHostOGL::DMABUFTextureHostOGL(TextureFlags aFlags
,
17 const SurfaceDescriptor
& aDesc
)
18 : TextureHost(TextureHostType::DMABUF
, aFlags
) {
19 MOZ_COUNT_CTOR(DMABUFTextureHostOGL
);
21 // DMABufSurface::CreateDMABufSurface() can fail, for instance when we're run
22 // out of file descriptors.
24 DMABufSurface::CreateDMABufSurface(aDesc
.get_SurfaceDescriptorDMABuf());
27 DMABUFTextureHostOGL::~DMABUFTextureHostOGL() {
28 MOZ_COUNT_DTOR(DMABUFTextureHostOGL
);
31 gfx::SurfaceFormat
DMABUFTextureHostOGL::GetFormat() const {
33 return gfx::SurfaceFormat::UNKNOWN
;
35 return mSurface
->GetFormat();
38 gfx::YUVColorSpace
DMABUFTextureHostOGL::GetYUVColorSpace() const {
40 return gfx::YUVColorSpace::Identity
;
42 return mSurface
->GetYUVColorSpace();
45 gfx::ColorRange
DMABUFTextureHostOGL::GetColorRange() const {
47 return gfx::ColorRange::LIMITED
;
49 return mSurface
->IsFullRange() ? gfx::ColorRange::FULL
50 : gfx::ColorRange::LIMITED
;
53 uint32_t DMABUFTextureHostOGL::NumSubTextures() {
54 return mSurface
? mSurface
->GetTextureCount() : 0;
57 gfx::IntSize
DMABUFTextureHostOGL::GetSize() const {
59 return gfx::IntSize();
61 return gfx::IntSize(mSurface
->GetWidth(), mSurface
->GetHeight());
64 gl::GLContext
* DMABUFTextureHostOGL::gl() const { return nullptr; }
66 void DMABUFTextureHostOGL::CreateRenderTexture(
67 const wr::ExternalImageId
& aExternalImageId
) {
68 MOZ_ASSERT(mExternalImageId
.isSome());
73 RefPtr
<wr::RenderTextureHost
> texture
=
74 new wr::RenderDMABUFTextureHost(mSurface
);
75 wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId
,
79 void DMABUFTextureHostOGL::PushResourceUpdates(
80 wr::TransactionBuilder
& aResources
, ResourceUpdateOp aOp
,
81 const Range
<wr::ImageKey
>& aImageKeys
, const wr::ExternalImageId
& aExtID
) {
86 auto method
= aOp
== TextureHost::ADD_IMAGE
87 ? &wr::TransactionBuilder::AddExternalImage
88 : &wr::TransactionBuilder::UpdateExternalImage
;
90 wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::Texture2D
);
92 switch (mSurface
->GetFormat()) {
93 case gfx::SurfaceFormat::R8G8B8X8
:
94 case gfx::SurfaceFormat::R8G8B8A8
:
95 case gfx::SurfaceFormat::B8G8R8X8
:
96 case gfx::SurfaceFormat::B8G8R8A8
: {
97 MOZ_ASSERT(aImageKeys
.length() == 1);
98 // XXX Add RGBA handling. Temporary hack to avoid crash
99 // With BGRA format setting, rendering works without problem.
100 wr::ImageDescriptor
descriptor(GetSize(), mSurface
->GetFormat());
101 (aResources
.*method
)(aImageKeys
[0], descriptor
, aExtID
, imageType
, 0,
102 /* aNormalizedUvs */ false);
105 case gfx::SurfaceFormat::NV12
: {
106 MOZ_ASSERT(aImageKeys
.length() == 2);
107 MOZ_ASSERT(mSurface
->GetTextureCount() == 2);
108 wr::ImageDescriptor
descriptor0(
109 gfx::IntSize(mSurface
->GetWidth(0), mSurface
->GetHeight(0)),
110 gfx::SurfaceFormat::A8
);
111 wr::ImageDescriptor
descriptor1(
112 gfx::IntSize(mSurface
->GetWidth(1), mSurface
->GetHeight(1)),
113 gfx::SurfaceFormat::R8G8
);
114 (aResources
.*method
)(aImageKeys
[0], descriptor0
, aExtID
, imageType
, 0,
115 /* aNormalizedUvs */ false);
116 (aResources
.*method
)(aImageKeys
[1], descriptor1
, aExtID
, imageType
, 1,
117 /* aNormalizedUvs */ false);
120 case gfx::SurfaceFormat::YUV420
: {
121 MOZ_ASSERT(aImageKeys
.length() == 3);
122 MOZ_ASSERT(mSurface
->GetTextureCount() == 3);
123 wr::ImageDescriptor
descriptor0(
124 gfx::IntSize(mSurface
->GetWidth(0), mSurface
->GetHeight(0)),
125 gfx::SurfaceFormat::A8
);
126 wr::ImageDescriptor
descriptor1(
127 gfx::IntSize(mSurface
->GetWidth(1), mSurface
->GetHeight(1)),
128 gfx::SurfaceFormat::A8
);
129 (aResources
.*method
)(aImageKeys
[0], descriptor0
, aExtID
, imageType
, 0,
130 /* aNormalizedUvs */ false);
131 (aResources
.*method
)(aImageKeys
[1], descriptor1
, aExtID
, imageType
, 1,
132 /* aNormalizedUvs */ false);
133 (aResources
.*method
)(aImageKeys
[2], descriptor1
, aExtID
, imageType
, 2,
134 /* aNormalizedUvs */ false);
138 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
143 void DMABUFTextureHostOGL::PushDisplayItems(
144 wr::DisplayListBuilder
& aBuilder
, const wr::LayoutRect
& aBounds
,
145 const wr::LayoutRect
& aClip
, wr::ImageRendering aFilter
,
146 const Range
<wr::ImageKey
>& aImageKeys
, PushDisplayItemFlagSet aFlags
) {
150 bool preferCompositorSurface
=
151 aFlags
.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE
);
152 switch (mSurface
->GetFormat()) {
153 case gfx::SurfaceFormat::R8G8B8X8
:
154 case gfx::SurfaceFormat::R8G8B8A8
:
155 case gfx::SurfaceFormat::B8G8R8A8
:
156 case gfx::SurfaceFormat::B8G8R8X8
: {
157 MOZ_ASSERT(aImageKeys
.length() == 1);
158 aBuilder
.PushImage(aBounds
, aClip
, true, false, aFilter
, aImageKeys
[0],
159 !(mFlags
& TextureFlags::NON_PREMULTIPLIED
),
160 wr::ColorF
{1.0f
, 1.0f
, 1.0f
, 1.0f
},
161 preferCompositorSurface
);
164 case gfx::SurfaceFormat::NV12
: {
165 MOZ_ASSERT(aImageKeys
.length() == 2);
166 MOZ_ASSERT(mSurface
->GetTextureCount() == 2);
167 // Those images can only be generated at present by the VAAPI H264 decoder
168 // which only supports 8 bits color depth.
169 aBuilder
.PushNV12Image(aBounds
, aClip
, true, aImageKeys
[0], aImageKeys
[1],
170 wr::ColorDepth::Color8
,
171 wr::ToWrYuvColorSpace(GetYUVColorSpace()),
172 wr::ToWrColorRange(GetColorRange()), aFilter
,
173 preferCompositorSurface
);
176 case gfx::SurfaceFormat::YUV420
: {
177 MOZ_ASSERT(aImageKeys
.length() == 3);
178 MOZ_ASSERT(mSurface
->GetTextureCount() == 3);
179 // Those images can only be generated at present by the VAAPI vp8 decoder
180 // which only supports 8 bits color depth.
181 aBuilder
.PushYCbCrPlanarImage(
182 aBounds
, aClip
, true, aImageKeys
[0], aImageKeys
[1], aImageKeys
[2],
183 wr::ColorDepth::Color8
, wr::ToWrYuvColorSpace(GetYUVColorSpace()),
184 wr::ToWrColorRange(GetColorRange()), aFilter
,
185 preferCompositorSurface
);
189 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
194 } // namespace mozilla::layers