MacIOSurfaceTextureHostOGL.cpp (10928B)
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 "MacIOSurfaceTextureHostOGL.h" 8 #include "mozilla/gfx/gfxVars.h" 9 #include "mozilla/gfx/MacIOSurface.h" 10 #include "mozilla/layers/GpuFence.h" 11 #include "mozilla/webrender/RenderMacIOSurfaceTextureHost.h" 12 #include "mozilla/webrender/RenderThread.h" 13 #include "mozilla/webrender/WebRenderAPI.h" 14 15 namespace mozilla { 16 namespace layers { 17 18 MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL( 19 TextureFlags aFlags, const SurfaceDescriptorMacIOSurface& aDescriptor) 20 : TextureHost(TextureHostType::MacIOSurface, aFlags), 21 mSurface(MacIOSurface::LookupSurface(aDescriptor.surfaceId(), 22 !aDescriptor.isOpaque(), 23 aDescriptor.yUVColorSpace())), 24 mGpuFence(aDescriptor.gpuFence()) { 25 MOZ_COUNT_CTOR(MacIOSurfaceTextureHostOGL); 26 if (!mSurface) { 27 gfxCriticalNote << "Failed to look up MacIOSurface"; 28 } 29 } 30 31 MacIOSurfaceTextureHostOGL::~MacIOSurfaceTextureHostOGL() { 32 MOZ_COUNT_DTOR(MacIOSurfaceTextureHostOGL); 33 } 34 35 gfx::SurfaceFormat MacIOSurfaceTextureHostOGL::GetFormat() const { 36 if (!mSurface) { 37 return gfx::SurfaceFormat::UNKNOWN; 38 } 39 return mSurface->GetFormat(); 40 } 41 42 gfx::SurfaceFormat MacIOSurfaceTextureHostOGL::GetReadFormat() const { 43 if (!mSurface) { 44 return gfx::SurfaceFormat::UNKNOWN; 45 } 46 return mSurface->GetReadFormat(); 47 } 48 49 gfx::IntSize MacIOSurfaceTextureHostOGL::GetSize() const { 50 if (!mSurface) { 51 return gfx::IntSize(); 52 } 53 return gfx::IntSize(mSurface->GetDevicePixelWidth(), 54 mSurface->GetDevicePixelHeight()); 55 } 56 57 gl::GLContext* MacIOSurfaceTextureHostOGL::gl() const { return nullptr; } 58 59 gfx::YUVColorSpace MacIOSurfaceTextureHostOGL::GetYUVColorSpace() const { 60 if (!mSurface) { 61 return gfx::YUVColorSpace::Identity; 62 } 63 return mSurface->GetYUVColorSpace(); 64 } 65 66 gfx::ColorRange MacIOSurfaceTextureHostOGL::GetColorRange() const { 67 if (!mSurface) { 68 return gfx::ColorRange::LIMITED; 69 } 70 return mSurface->IsFullRange() ? gfx::ColorRange::FULL 71 : gfx::ColorRange::LIMITED; 72 } 73 74 void MacIOSurfaceTextureHostOGL::CreateRenderTexture( 75 const wr::ExternalImageId& aExternalImageId) { 76 MOZ_ASSERT(mExternalImageId.isSome()); 77 78 RefPtr<wr::RenderTextureHost> texture = 79 new wr::RenderMacIOSurfaceTextureHost(GetMacIOSurface(), mGpuFence); 80 81 bool isDRM = (bool)(mFlags & TextureFlags::DRM_SOURCE); 82 texture->SetIsFromDRMSource(isDRM); 83 84 wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId, 85 texture.forget()); 86 } 87 88 uint32_t MacIOSurfaceTextureHostOGL::NumSubTextures() { 89 if (!mSurface) { 90 return 0; 91 } 92 93 switch (GetFormat()) { 94 case gfx::SurfaceFormat::R8G8B8X8: 95 case gfx::SurfaceFormat::R8G8B8A8: 96 case gfx::SurfaceFormat::B8G8R8A8: 97 case gfx::SurfaceFormat::B8G8R8X8: 98 case gfx::SurfaceFormat::YUY2: { 99 return 1; 100 } 101 case gfx::SurfaceFormat::NV12: 102 case gfx::SurfaceFormat::P010: 103 case gfx::SurfaceFormat::NV16: { 104 return 2; 105 } 106 default: { 107 MOZ_ASSERT_UNREACHABLE("unexpected format"); 108 return 1; 109 } 110 } 111 } 112 113 void MacIOSurfaceTextureHostOGL::PushResourceUpdates( 114 wr::TransactionBuilder& aResources, ResourceUpdateOp aOp, 115 const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) { 116 MOZ_ASSERT(mSurface); 117 118 auto method = aOp == TextureHost::ADD_IMAGE 119 ? &wr::TransactionBuilder::AddExternalImage 120 : &wr::TransactionBuilder::UpdateExternalImage; 121 auto imageType = 122 wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::TextureRect); 123 124 switch (GetFormat()) { 125 case gfx::SurfaceFormat::B8G8R8A8: 126 case gfx::SurfaceFormat::B8G8R8X8: { 127 MOZ_ASSERT(aImageKeys.length() == 1); 128 MOZ_ASSERT(mSurface->GetPlaneCount() == 0); 129 // The internal pixel format of MacIOSurface is always BGRX or BGRA 130 // format. 131 auto format = GetFormat() == gfx::SurfaceFormat::B8G8R8A8 132 ? gfx::SurfaceFormat::B8G8R8A8 133 : gfx::SurfaceFormat::B8G8R8X8; 134 wr::ImageDescriptor descriptor(GetSize(), format); 135 (aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0, 136 /* aNormalizedUvs */ false); 137 break; 138 } 139 case gfx::SurfaceFormat::YUY2: { 140 // This is the special buffer format. The buffer contents could be a 141 // converted RGB interleaving data or a YCbCr interleaving data depending 142 // on the different platform setting. (e.g. It will be RGB at OpenGL 2.1 143 // and YCbCr at OpenGL 3.1) 144 MOZ_ASSERT(aImageKeys.length() == 1); 145 MOZ_ASSERT(mSurface->GetPlaneCount() == 0); 146 wr::ImageDescriptor descriptor(GetSize(), gfx::SurfaceFormat::B8G8R8X8); 147 (aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0, 148 /* aNormalizedUvs */ false); 149 break; 150 } 151 case gfx::SurfaceFormat::NV12: { 152 MOZ_ASSERT(aImageKeys.length() == 2); 153 MOZ_ASSERT(mSurface->GetPlaneCount() == 2); 154 wr::ImageDescriptor descriptor0( 155 gfx::IntSize(mSurface->GetDevicePixelWidth(0), 156 mSurface->GetDevicePixelHeight(0)), 157 gfx::SurfaceFormat::A8); 158 wr::ImageDescriptor descriptor1( 159 gfx::IntSize(mSurface->GetDevicePixelWidth(1), 160 mSurface->GetDevicePixelHeight(1)), 161 gfx::SurfaceFormat::R8G8); 162 (aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0, 163 /* aNormalizedUvs */ false); 164 (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1, 165 /* aNormalizedUvs */ false); 166 break; 167 } 168 case gfx::SurfaceFormat::P010: 169 case gfx::SurfaceFormat::P016: { 170 MOZ_ASSERT(aImageKeys.length() == 2); 171 MOZ_ASSERT(mSurface->GetPlaneCount() == 2); 172 wr::ImageDescriptor descriptor0( 173 gfx::IntSize(mSurface->GetDevicePixelWidth(0), 174 mSurface->GetDevicePixelHeight(0)), 175 gfx::SurfaceFormat::A16); 176 wr::ImageDescriptor descriptor1( 177 gfx::IntSize(mSurface->GetDevicePixelWidth(1), 178 mSurface->GetDevicePixelHeight(1)), 179 gfx::SurfaceFormat::R16G16); 180 (aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0, 181 /* aNormalizedUvs */ false); 182 (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1, 183 /* aNormalizedUvs */ false); 184 break; 185 } 186 case gfx::SurfaceFormat::NV16: { 187 MOZ_ASSERT(aImageKeys.length() == 2); 188 MOZ_ASSERT(mSurface->GetPlaneCount() == 2); 189 wr::ImageDescriptor descriptor0( 190 gfx::IntSize(mSurface->GetDevicePixelWidth(0), 191 mSurface->GetDevicePixelHeight(0)), 192 gfx::SurfaceFormat::A16); 193 wr::ImageDescriptor descriptor1( 194 gfx::IntSize(mSurface->GetDevicePixelWidth(1), 195 mSurface->GetDevicePixelHeight(1)), 196 gfx::SurfaceFormat::R16G16); 197 (aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0, 198 /* aNormalizedUvs */ false); 199 (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1, 200 /* aNormalizedUvs */ false); 201 break; 202 } 203 default: { 204 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 205 } 206 } 207 } 208 209 void MacIOSurfaceTextureHostOGL::PushDisplayItems( 210 wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds, 211 const wr::LayoutRect& aClip, wr::ImageRendering aFilter, 212 const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) { 213 bool preferCompositorSurface = 214 aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE); 215 switch (GetFormat()) { 216 case gfx::SurfaceFormat::B8G8R8A8: 217 case gfx::SurfaceFormat::B8G8R8X8: { 218 MOZ_ASSERT(aImageKeys.length() == 1); 219 MOZ_ASSERT(mSurface->GetPlaneCount() == 0); 220 // We disable external compositing for RGB surfaces for now until 221 // we've tested support more thoroughly. Bug 1667917. 222 aBuilder.PushImage(aBounds, aClip, true, false, aFilter, aImageKeys[0], 223 !(mFlags & TextureFlags::NON_PREMULTIPLIED), 224 wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}, 225 preferCompositorSurface, 226 /* aSupportsExternalCompositing */ true); 227 break; 228 } 229 case gfx::SurfaceFormat::YUY2: { 230 MOZ_ASSERT(aImageKeys.length() == 1); 231 MOZ_ASSERT(mSurface->GetPlaneCount() == 0); 232 // Those images can only be generated at present by the Apple H264 decoder 233 // which only supports 8 bits color depth. 234 aBuilder.PushYCbCrInterleavedImage( 235 aBounds, aClip, true, aImageKeys[0], wr::ColorDepth::Color8, 236 wr::ToWrYuvColorSpace(GetYUVColorSpace()), 237 wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, 238 /* aSupportsExternalCompositing */ true); 239 break; 240 } 241 case gfx::SurfaceFormat::NV12: { 242 MOZ_ASSERT(aImageKeys.length() == 2); 243 MOZ_ASSERT(mSurface->GetPlaneCount() == 2); 244 aBuilder.PushNV12Image( 245 aBounds, aClip, true, aImageKeys[0], aImageKeys[1], 246 wr::ColorDepth::Color8, wr::ToWrYuvColorSpace(GetYUVColorSpace()), 247 wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, 248 /* aSupportsExternalCompositing */ true); 249 break; 250 } 251 case gfx::SurfaceFormat::P010: 252 case gfx::SurfaceFormat::P016: { 253 MOZ_ASSERT(aImageKeys.length() == 2); 254 MOZ_ASSERT(mSurface->GetPlaneCount() == 2); 255 aBuilder.PushP010Image( 256 aBounds, aClip, true, aImageKeys[0], aImageKeys[1], 257 wr::ColorDepth::Color10, wr::ToWrYuvColorSpace(GetYUVColorSpace()), 258 wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, 259 /* aSupportsExternalCompositing */ true); 260 break; 261 } 262 case gfx::SurfaceFormat::NV16: { 263 MOZ_ASSERT(aImageKeys.length() == 2); 264 MOZ_ASSERT(mSurface->GetPlaneCount() == 2); 265 aBuilder.PushNV16Image( 266 aBounds, aClip, true, aImageKeys[0], aImageKeys[1], 267 wr::ColorDepth::Color10, wr::ToWrYuvColorSpace(GetYUVColorSpace()), 268 wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, 269 /* aSupportsExternalCompositing */ true); 270 break; 271 } 272 default: { 273 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 274 } 275 } 276 } 277 278 } // namespace layers 279 } // namespace mozilla