Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release
[gecko.git] / gfx / webrender_bindings / RenderTextureHostSWGL.cpp
blobad2d960837e0779cdf27e0572a0de00348eee3e4
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 "RenderTextureHostSWGL.h"
9 #include "mozilla/gfx/Logging.h"
10 #include "mozilla/layers/TextureHost.h"
11 #include "RenderThread.h"
13 namespace mozilla {
14 namespace wr {
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)));
25 texInit = true;
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();
35 return false;
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::YUV:
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;
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;
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::YUV422:
73 MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_8);
74 internalFormat = LOCAL_GL_RGB_RAW_422_APPLE;
75 break;
76 default:
77 MOZ_RELEASE_ASSERT(false, "Unhandled external image format");
78 break;
80 wr_swgl_set_texture_buffer(mContext, plane.mTexture, internalFormat,
81 plane.mSize.width, plane.mSize.height,
82 plane.mStride, plane.mData, 0, 0);
84 if (texInit) {
85 // Initialize the mip filters to linear by default.
86 for (const auto& plane : mPlanes) {
87 wr_swgl_set_texture_parameter(mContext, plane.mTexture,
88 LOCAL_GL_TEXTURE_MIN_FILTER,
89 LOCAL_GL_LINEAR);
90 wr_swgl_set_texture_parameter(mContext, plane.mTexture,
91 LOCAL_GL_TEXTURE_MAG_FILTER,
92 LOCAL_GL_LINEAR);
95 return true;
98 bool RenderTextureHostSWGL::SetContext(void* aContext) {
99 if (mContext != aContext) {
100 CleanupPlanes();
101 mContext = aContext;
102 wr_swgl_reference_context(mContext);
104 return mContext != nullptr;
107 wr::WrExternalImage RenderTextureHostSWGL::LockSWGL(
108 uint8_t aChannelIndex, void* aContext, RenderCompositor* aCompositor) {
109 if (!SetContext(aContext)) {
110 return InvalidToWrExternalImage();
112 if (!mLocked) {
113 if (!UpdatePlanes(aCompositor)) {
114 return InvalidToWrExternalImage();
116 mLocked = true;
118 if (aChannelIndex >= mPlanes.size()) {
119 return InvalidToWrExternalImage();
121 const PlaneInfo& plane = mPlanes[aChannelIndex];
123 const auto uvs = GetUvCoords(plane.mSize);
125 // Prefer native textures, unless our backend forbids it.
126 // If the GetUvCoords call above returned anything other than the default,
127 // for example if this is a RenderAndroidSurfaceTextureHost, then this won't
128 // be handled correctly in the RawDataToWrExternalImage path. But we shouldn't
129 // hit this path in practice with a RenderAndroidSurfaceTextureHost.
130 layers::TextureHost::NativeTexturePolicy policy =
131 layers::TextureHost::BackendNativeTexturePolicy(
132 layers::WebRenderBackend::SOFTWARE, plane.mSize);
133 return policy == layers::TextureHost::NativeTexturePolicy::FORBID
134 ? RawDataToWrExternalImage((uint8_t*)plane.mData,
135 plane.mStride * plane.mSize.height)
136 : NativeTextureToWrExternalImage(plane.mTexture, uvs.first.x,
137 uvs.first.y, uvs.second.x,
138 uvs.second.y);
141 void RenderTextureHostSWGL::UnlockSWGL() {
142 if (mLocked) {
143 mLocked = false;
144 UnmapPlanes();
148 void RenderTextureHostSWGL::CleanupPlanes() {
149 if (!mContext) {
150 return;
152 if (!mPlanes.empty()) {
153 wr_swgl_make_current(mContext);
154 for (const auto& plane : mPlanes) {
155 wr_swgl_delete_texture(mContext, plane.mTexture);
157 mPlanes.clear();
159 wr_swgl_destroy_context(mContext);
160 mContext = nullptr;
163 RenderTextureHostSWGL::~RenderTextureHostSWGL() { CleanupPlanes(); }
165 bool RenderTextureHostSWGL::LockSWGLCompositeSurface(
166 void* aContext, wr::SWGLCompositeSurfaceInfo* aInfo) {
167 if (!SetContext(aContext)) {
168 return false;
170 if (!mLocked) {
171 if (!UpdatePlanes(nullptr)) {
172 return false;
174 mLocked = true;
176 MOZ_ASSERT(mPlanes.size() <= 3);
177 for (size_t i = 0; i < mPlanes.size(); i++) {
178 aInfo->textures[i] = mPlanes[i].mTexture;
180 switch (GetFormat()) {
181 case gfx::SurfaceFormat::YUV:
182 case gfx::SurfaceFormat::NV12:
183 case gfx::SurfaceFormat::P010:
184 case gfx::SurfaceFormat::YUV422: {
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;
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;
200 aInfo->size.width = mPlanes[0].mSize.width;
201 aInfo->size.height = mPlanes[0].mSize.height;
202 return true;
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;
211 RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL();
212 if (!swglTex) {
213 return false;
215 return swglTex->LockSWGLCompositeSurface(aContext, aInfo);
218 void wr_swgl_unlock_composite_surface(void* aContext, wr::ExternalImageId aId) {
219 RenderTextureHost* texture = RenderThread::Get()->GetRenderTexture(aId);
220 if (!texture) {
221 return;
223 RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL();
224 if (!swglTex) {
225 return;
227 swglTex->UnlockSWGL();
230 } // namespace wr
231 } // namespace mozilla