RenderTextureHostSWGL.cpp (7461B)
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 "RenderTextureHostSWGL.h" 8 9 #include "mozilla/gfx/Logging.h" 10 #include "mozilla/layers/TextureHost.h" 11 #include "RenderThread.h" 12 13 namespace mozilla { 14 namespace wr { 15 16 bool RenderTextureHostSWGL::UpdatePlanes(RenderCompositor* aCompositor) { 17 wr_swgl_make_current(mContext); 18 size_t planeCount = GetPlaneCount(); 19 bool texInit = false; 20 if (mPlanes.size() < planeCount) { 21 mPlanes.reserve(planeCount); 22 while (mPlanes.size() < planeCount) { 23 mPlanes.push_back(PlaneInfo(wr_swgl_gen_texture(mContext))); 24 } 25 texInit = true; 26 } 27 gfx::SurfaceFormat format = GetFormat(); 28 gfx::ColorDepth colorDepth = GetColorDepth(); 29 for (size_t i = 0; i < planeCount; i++) { 30 PlaneInfo& plane = mPlanes[i]; 31 if (!MapPlane(aCompositor, i, plane)) { 32 if (i > 0) { 33 UnmapPlanes(); 34 } 35 return false; 36 } 37 GLenum internalFormat = 0; 38 switch (format) { 39 case gfx::SurfaceFormat::B8G8R8A8: 40 case gfx::SurfaceFormat::B8G8R8X8: 41 MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_8); 42 internalFormat = LOCAL_GL_RGBA8; 43 break; 44 case gfx::SurfaceFormat::YUV420: 45 switch (colorDepth) { 46 case gfx::ColorDepth::COLOR_8: 47 internalFormat = LOCAL_GL_R8; 48 break; 49 case gfx::ColorDepth::COLOR_10: 50 case gfx::ColorDepth::COLOR_12: 51 case gfx::ColorDepth::COLOR_16: 52 internalFormat = LOCAL_GL_R16; 53 break; 54 } 55 break; 56 case gfx::SurfaceFormat::NV12: 57 switch (colorDepth) { 58 case gfx::ColorDepth::COLOR_8: 59 internalFormat = i > 0 ? LOCAL_GL_RG8 : LOCAL_GL_R8; 60 break; 61 case gfx::ColorDepth::COLOR_10: 62 case gfx::ColorDepth::COLOR_12: 63 case gfx::ColorDepth::COLOR_16: 64 internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16; 65 break; 66 } 67 break; 68 case gfx::SurfaceFormat::P010: 69 MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_10); 70 internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16; 71 break; 72 case gfx::SurfaceFormat::P016: 73 MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_16); 74 internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16; 75 break; 76 case gfx::SurfaceFormat::YUY2: 77 MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_8); 78 internalFormat = LOCAL_GL_RGB_RAW_422_APPLE; 79 break; 80 default: 81 MOZ_RELEASE_ASSERT(false, "Unhandled external image format"); 82 break; 83 } 84 wr_swgl_set_texture_buffer(mContext, plane.mTexture, internalFormat, 85 plane.mSize.width, plane.mSize.height, 86 plane.mStride, plane.mData, 0, 0); 87 } 88 if (texInit) { 89 // Initialize the mip filters to linear by default. 90 for (const auto& plane : mPlanes) { 91 wr_swgl_set_texture_parameter(mContext, plane.mTexture, 92 LOCAL_GL_TEXTURE_MIN_FILTER, 93 LOCAL_GL_LINEAR); 94 wr_swgl_set_texture_parameter(mContext, plane.mTexture, 95 LOCAL_GL_TEXTURE_MAG_FILTER, 96 LOCAL_GL_LINEAR); 97 } 98 } 99 return true; 100 } 101 102 bool RenderTextureHostSWGL::SetContext(void* aContext) { 103 if (mContext != aContext) { 104 CleanupPlanes(); 105 mContext = aContext; 106 wr_swgl_reference_context(mContext); 107 } 108 return mContext != nullptr; 109 } 110 111 wr::WrExternalImage RenderTextureHostSWGL::LockSWGL( 112 uint8_t aChannelIndex, void* aContext, RenderCompositor* aCompositor) { 113 if (!SetContext(aContext)) { 114 return InvalidToWrExternalImage(); 115 } 116 if (!mLocked) { 117 if (!UpdatePlanes(aCompositor)) { 118 return InvalidToWrExternalImage(); 119 } 120 mLocked = true; 121 } 122 if (aChannelIndex >= mPlanes.size()) { 123 return InvalidToWrExternalImage(); 124 } 125 const PlaneInfo& plane = mPlanes[aChannelIndex]; 126 127 // Prefer native textures, unless our backend forbids it. 128 layers::TextureHost::NativeTexturePolicy policy = 129 layers::TextureHost::BackendNativeTexturePolicy( 130 layers::WebRenderBackend::SOFTWARE, plane.mSize); 131 return policy == layers::TextureHost::NativeTexturePolicy::FORBID 132 ? RawDataToWrExternalImage((uint8_t*)plane.mData, 133 plane.mStride * plane.mSize.height) 134 : NativeTextureToWrExternalImage( 135 plane.mTexture, 0.0, 0.0, 136 static_cast<float>(plane.mSize.width), 137 static_cast<float>(plane.mSize.height)); 138 } 139 140 void RenderTextureHostSWGL::UnlockSWGL() { 141 if (mLocked) { 142 mLocked = false; 143 UnmapPlanes(); 144 } 145 } 146 147 void RenderTextureHostSWGL::CleanupPlanes() { 148 if (!mContext) { 149 return; 150 } 151 if (!mPlanes.empty()) { 152 wr_swgl_make_current(mContext); 153 for (const auto& plane : mPlanes) { 154 wr_swgl_delete_texture(mContext, plane.mTexture); 155 } 156 mPlanes.clear(); 157 } 158 wr_swgl_destroy_context(mContext); 159 mContext = nullptr; 160 } 161 162 RenderTextureHostSWGL::~RenderTextureHostSWGL() { CleanupPlanes(); } 163 164 bool RenderTextureHostSWGL::LockSWGLCompositeSurface( 165 void* aContext, wr::SWGLCompositeSurfaceInfo* aInfo) { 166 if (!SetContext(aContext)) { 167 return false; 168 } 169 if (!mLocked) { 170 if (!UpdatePlanes(nullptr)) { 171 return false; 172 } 173 mLocked = true; 174 } 175 MOZ_ASSERT(mPlanes.size() <= 3); 176 for (size_t i = 0; i < mPlanes.size(); i++) { 177 aInfo->textures[i] = mPlanes[i].mTexture; 178 } 179 switch (GetFormat()) { 180 case gfx::SurfaceFormat::YUV420: 181 case gfx::SurfaceFormat::NV12: 182 case gfx::SurfaceFormat::P010: 183 case gfx::SurfaceFormat::P016: 184 case gfx::SurfaceFormat::YUY2: { 185 aInfo->yuv_planes = mPlanes.size(); 186 auto colorSpace = GetYUVColorSpace(); 187 aInfo->color_space = ToWrYuvRangedColorSpace(colorSpace); 188 auto colorDepth = GetColorDepth(); 189 aInfo->color_depth = ToWrColorDepth(colorDepth); 190 break; 191 } 192 case gfx::SurfaceFormat::B8G8R8A8: 193 case gfx::SurfaceFormat::B8G8R8X8: 194 break; 195 default: 196 gfxCriticalNote << "Unhandled external image format: " << GetFormat(); 197 MOZ_RELEASE_ASSERT(false, "Unhandled external image format"); 198 break; 199 } 200 aInfo->size.width = mPlanes[0].mSize.width; 201 aInfo->size.height = mPlanes[0].mSize.height; 202 return true; 203 } 204 205 bool wr_swgl_lock_composite_surface(void* aContext, wr::ExternalImageId aId, 206 wr::SWGLCompositeSurfaceInfo* aInfo) { 207 RenderTextureHost* texture = RenderThread::Get()->GetRenderTexture(aId); 208 if (!texture) { 209 return false; 210 } 211 RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL(); 212 if (!swglTex) { 213 return false; 214 } 215 return swglTex->LockSWGLCompositeSurface(aContext, aInfo); 216 } 217 218 void wr_swgl_unlock_composite_surface(void* aContext, wr::ExternalImageId aId) { 219 RenderTextureHost* texture = RenderThread::Get()->GetRenderTexture(aId); 220 if (!texture) { 221 return; 222 } 223 RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL(); 224 if (!swglTex) { 225 return; 226 } 227 swglTex->UnlockSWGL(); 228 } 229 230 } // namespace wr 231 } // namespace mozilla