DMABUFTextureHostOGL.cpp (8805B)
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/. */ 6 7 #include "DMABUFTextureHostOGL.h" 8 #include "mozilla/widget/DMABufSurface.h" 9 #include "mozilla/widget/DMABufFormats.h" 10 #include "mozilla/webrender/RenderDMABUFTextureHost.h" 11 #include "mozilla/webrender/RenderThread.h" 12 #include "mozilla/webrender/WebRenderAPI.h" 13 #include "GLContextEGL.h" 14 15 namespace mozilla::layers { 16 17 DMABUFTextureHostOGL::DMABUFTextureHostOGL(TextureFlags aFlags, 18 const SurfaceDescriptor& aDesc) 19 : TextureHost(TextureHostType::DMABUF, aFlags) { 20 MOZ_COUNT_CTOR(DMABUFTextureHostOGL); 21 22 // DMABufSurface::CreateDMABufSurface() can fail, for instance when we're run 23 // out of file descriptors. 24 mSurface = 25 DMABufSurface::CreateDMABufSurface(aDesc.get_SurfaceDescriptorDMABuf()); 26 } 27 28 DMABUFTextureHostOGL::~DMABUFTextureHostOGL() { 29 MOZ_COUNT_DTOR(DMABUFTextureHostOGL); 30 } 31 32 gfx::SurfaceFormat DMABUFTextureHostOGL::GetFormat() const { 33 if (!mSurface) { 34 return gfx::SurfaceFormat::UNKNOWN; 35 } 36 return mSurface->GetFormat(); 37 } 38 39 gfx::YUVColorSpace DMABUFTextureHostOGL::GetYUVColorSpace() const { 40 if (!mSurface) { 41 return gfx::YUVColorSpace::Identity; 42 } 43 return mSurface->GetYUVColorSpace(); 44 } 45 46 gfx::ColorRange DMABUFTextureHostOGL::GetColorRange() const { 47 if (!mSurface) { 48 return gfx::ColorRange::LIMITED; 49 } 50 return mSurface->IsFullRange() ? gfx::ColorRange::FULL 51 : gfx::ColorRange::LIMITED; 52 } 53 54 uint32_t DMABUFTextureHostOGL::NumSubTextures() { 55 return mSurface ? mSurface->GetTextureCount() : 0; 56 } 57 58 gfx::IntSize DMABUFTextureHostOGL::GetSize() const { 59 if (!mSurface) { 60 return gfx::IntSize(); 61 } 62 return gfx::IntSize(mSurface->GetWidth(), mSurface->GetHeight()); 63 } 64 65 gl::GLContext* DMABUFTextureHostOGL::gl() const { return nullptr; } 66 67 void DMABUFTextureHostOGL::CreateRenderTexture( 68 const wr::ExternalImageId& aExternalImageId) { 69 MOZ_ASSERT(mExternalImageId.isSome()); 70 71 if (!mSurface) { 72 return; 73 } 74 RefPtr<wr::RenderTextureHost> texture = 75 new wr::RenderDMABUFTextureHost(mSurface); 76 wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId, 77 texture.forget()); 78 } 79 80 void DMABUFTextureHostOGL::PushResourceUpdates( 81 wr::TransactionBuilder& aResources, ResourceUpdateOp aOp, 82 const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) { 83 if (!mSurface) { 84 return; 85 } 86 87 auto method = aOp == TextureHost::ADD_IMAGE 88 ? &wr::TransactionBuilder::AddExternalImage 89 : &wr::TransactionBuilder::UpdateExternalImage; 90 auto imageType = 91 wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::Texture2D); 92 93 switch (mSurface->GetFormat()) { 94 case gfx::SurfaceFormat::R8G8B8X8: 95 case gfx::SurfaceFormat::R8G8B8A8: 96 case gfx::SurfaceFormat::B8G8R8X8: 97 case gfx::SurfaceFormat::B8G8R8A8: { 98 MOZ_ASSERT(aImageKeys.length() == 1); 99 // XXX Add RGBA handling. Temporary hack to avoid crash 100 // With BGRA format setting, rendering works without problem. 101 wr::ImageDescriptor descriptor(GetSize(), mSurface->GetFormat()); 102 (aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0, 103 /* aNormalizedUvs */ false); 104 break; 105 } 106 case gfx::SurfaceFormat::NV12: { 107 MOZ_ASSERT(aImageKeys.length() == 2); 108 MOZ_ASSERT(mSurface->GetTextureCount() == 2); 109 wr::ImageDescriptor descriptor0( 110 gfx::IntSize(mSurface->GetWidth(0), mSurface->GetHeight(0)), 111 gfx::SurfaceFormat::A8); 112 wr::ImageDescriptor descriptor1( 113 gfx::IntSize(mSurface->GetWidth(1), mSurface->GetHeight(1)), 114 gfx::SurfaceFormat::R8G8); 115 (aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0, 116 /* aNormalizedUvs */ false); 117 (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1, 118 /* aNormalizedUvs */ false); 119 break; 120 } 121 case gfx::SurfaceFormat::YUV420: { 122 MOZ_ASSERT(aImageKeys.length() == 3); 123 MOZ_ASSERT(mSurface->GetTextureCount() == 3); 124 wr::ImageDescriptor descriptor0( 125 gfx::IntSize(mSurface->GetWidth(0), mSurface->GetHeight(0)), 126 gfx::SurfaceFormat::A8); 127 wr::ImageDescriptor descriptor1( 128 gfx::IntSize(mSurface->GetWidth(1), mSurface->GetHeight(1)), 129 gfx::SurfaceFormat::A8); 130 (aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0, 131 /* aNormalizedUvs */ false); 132 (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1, 133 /* aNormalizedUvs */ false); 134 (aResources.*method)(aImageKeys[2], descriptor1, aExtID, imageType, 2, 135 /* aNormalizedUvs */ false); 136 break; 137 } 138 case gfx::SurfaceFormat::P010: 139 case gfx::SurfaceFormat::P016: { 140 MOZ_ASSERT(aImageKeys.length() == 2); 141 MOZ_ASSERT(mSurface->GetTextureCount() == 2); 142 wr::ImageDescriptor descriptor0( 143 gfx::IntSize(mSurface->GetWidth(0), mSurface->GetHeight(0)), 144 gfx::SurfaceFormat::A16); 145 wr::ImageDescriptor descriptor1( 146 gfx::IntSize(mSurface->GetWidth(1), mSurface->GetHeight(1)), 147 gfx::SurfaceFormat::R16G16); 148 (aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0, 149 /* aNormalizedUvs */ false); 150 (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1, 151 /* aNormalizedUvs */ false); 152 break; 153 } 154 default: { 155 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 156 } 157 } 158 } 159 160 void DMABUFTextureHostOGL::PushDisplayItems( 161 wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds, 162 const wr::LayoutRect& aClip, wr::ImageRendering aFilter, 163 const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) { 164 if (!mSurface) { 165 return; 166 } 167 bool preferCompositorSurface = 168 aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE); 169 bool supportsDirectComposition = 170 widget::GetGlobalDMABufFormats()->SupportsDirectComposition( 171 mSurface->GetFormat()); 172 173 switch (mSurface->GetFormat()) { 174 case gfx::SurfaceFormat::R8G8B8X8: 175 case gfx::SurfaceFormat::R8G8B8A8: 176 case gfx::SurfaceFormat::B8G8R8A8: 177 case gfx::SurfaceFormat::B8G8R8X8: { 178 MOZ_ASSERT(aImageKeys.length() == 1); 179 aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0], 180 !(mFlags & TextureFlags::NON_PREMULTIPLIED), 181 wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}, 182 preferCompositorSurface, supportsDirectComposition); 183 break; 184 } 185 case gfx::SurfaceFormat::NV12: { 186 MOZ_ASSERT(aImageKeys.length() == 2); 187 MOZ_ASSERT(mSurface->GetTextureCount() == 2); 188 // Those images can only be generated at present by the VAAPI H264 decoder 189 // which only supports 8 bits color depth. 190 aBuilder.PushNV12Image( 191 aBounds, aClip, true, aImageKeys[0], aImageKeys[1], 192 wr::ColorDepth::Color8, wr::ToWrYuvColorSpace(GetYUVColorSpace()), 193 wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, 194 supportsDirectComposition); 195 break; 196 } 197 case gfx::SurfaceFormat::YUV420: { 198 MOZ_ASSERT(aImageKeys.length() == 3); 199 MOZ_ASSERT(mSurface->GetTextureCount() == 3); 200 // Those images can only be generated at present by the VAAPI vp8 decoder 201 // which only supports 8 bits color depth. 202 aBuilder.PushYCbCrPlanarImage( 203 aBounds, aClip, true, aImageKeys[0], aImageKeys[1], aImageKeys[2], 204 wr::ColorDepth::Color8, wr::ToWrYuvColorSpace(GetYUVColorSpace()), 205 wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, 206 supportsDirectComposition); 207 break; 208 } 209 case gfx::SurfaceFormat::P010: 210 case gfx::SurfaceFormat::P016: { 211 MOZ_ASSERT(aImageKeys.length() == 2); 212 MOZ_ASSERT(mSurface->GetTextureCount() == 2); 213 aBuilder.PushP010Image( 214 aBounds, aClip, true, aImageKeys[0], aImageKeys[1], 215 wr::ColorDepth::Color10, wr::ToWrYuvColorSpace(GetYUVColorSpace()), 216 wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, 217 supportsDirectComposition); 218 break; 219 } 220 default: { 221 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 222 } 223 } 224 } 225 226 } // namespace mozilla::layers