mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
f5be562cbd
Backed out changeset c53591077218 (bug 1812982) Backed out changeset 9c11387675b1 (bug 1812982)
232 lines
7.4 KiB
C++
232 lines
7.4 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "RenderTextureHostSWGL.h"
|
|
|
|
#include "mozilla/gfx/Logging.h"
|
|
#include "mozilla/layers/TextureHost.h"
|
|
#include "RenderThread.h"
|
|
|
|
namespace mozilla {
|
|
namespace wr {
|
|
|
|
bool RenderTextureHostSWGL::UpdatePlanes(RenderCompositor* aCompositor) {
|
|
wr_swgl_make_current(mContext);
|
|
size_t planeCount = GetPlaneCount();
|
|
bool texInit = false;
|
|
if (mPlanes.size() < planeCount) {
|
|
mPlanes.reserve(planeCount);
|
|
while (mPlanes.size() < planeCount) {
|
|
mPlanes.push_back(PlaneInfo(wr_swgl_gen_texture(mContext)));
|
|
}
|
|
texInit = true;
|
|
}
|
|
gfx::SurfaceFormat format = GetFormat();
|
|
gfx::ColorDepth colorDepth = GetColorDepth();
|
|
for (size_t i = 0; i < planeCount; i++) {
|
|
PlaneInfo& plane = mPlanes[i];
|
|
if (!MapPlane(aCompositor, i, plane)) {
|
|
if (i > 0) {
|
|
UnmapPlanes();
|
|
}
|
|
return false;
|
|
}
|
|
GLenum internalFormat = 0;
|
|
switch (format) {
|
|
case gfx::SurfaceFormat::B8G8R8A8:
|
|
case gfx::SurfaceFormat::B8G8R8X8:
|
|
MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_8);
|
|
internalFormat = LOCAL_GL_RGBA8;
|
|
break;
|
|
case gfx::SurfaceFormat::YUV:
|
|
switch (colorDepth) {
|
|
case gfx::ColorDepth::COLOR_8:
|
|
internalFormat = LOCAL_GL_R8;
|
|
break;
|
|
case gfx::ColorDepth::COLOR_10:
|
|
case gfx::ColorDepth::COLOR_12:
|
|
case gfx::ColorDepth::COLOR_16:
|
|
internalFormat = LOCAL_GL_R16;
|
|
break;
|
|
}
|
|
break;
|
|
case gfx::SurfaceFormat::NV12:
|
|
switch (colorDepth) {
|
|
case gfx::ColorDepth::COLOR_8:
|
|
internalFormat = i > 0 ? LOCAL_GL_RG8 : LOCAL_GL_R8;
|
|
break;
|
|
case gfx::ColorDepth::COLOR_10:
|
|
case gfx::ColorDepth::COLOR_12:
|
|
case gfx::ColorDepth::COLOR_16:
|
|
internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16;
|
|
break;
|
|
}
|
|
break;
|
|
case gfx::SurfaceFormat::P010:
|
|
MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_10);
|
|
internalFormat = i > 0 ? LOCAL_GL_RG16 : LOCAL_GL_R16;
|
|
break;
|
|
case gfx::SurfaceFormat::YUV422:
|
|
MOZ_ASSERT(colorDepth == gfx::ColorDepth::COLOR_8);
|
|
internalFormat = LOCAL_GL_RGB_RAW_422_APPLE;
|
|
break;
|
|
default:
|
|
MOZ_RELEASE_ASSERT(false, "Unhandled external image format");
|
|
break;
|
|
}
|
|
wr_swgl_set_texture_buffer(mContext, plane.mTexture, internalFormat,
|
|
plane.mSize.width, plane.mSize.height,
|
|
plane.mStride, plane.mData, 0, 0);
|
|
}
|
|
if (texInit) {
|
|
// Initialize the mip filters to linear by default.
|
|
for (const auto& plane : mPlanes) {
|
|
wr_swgl_set_texture_parameter(mContext, plane.mTexture,
|
|
LOCAL_GL_TEXTURE_MIN_FILTER,
|
|
LOCAL_GL_LINEAR);
|
|
wr_swgl_set_texture_parameter(mContext, plane.mTexture,
|
|
LOCAL_GL_TEXTURE_MAG_FILTER,
|
|
LOCAL_GL_LINEAR);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool RenderTextureHostSWGL::SetContext(void* aContext) {
|
|
if (mContext != aContext) {
|
|
CleanupPlanes();
|
|
mContext = aContext;
|
|
wr_swgl_reference_context(mContext);
|
|
}
|
|
return mContext != nullptr;
|
|
}
|
|
|
|
wr::WrExternalImage RenderTextureHostSWGL::LockSWGL(
|
|
uint8_t aChannelIndex, void* aContext, RenderCompositor* aCompositor) {
|
|
if (!SetContext(aContext)) {
|
|
return InvalidToWrExternalImage();
|
|
}
|
|
if (!mLocked) {
|
|
if (!UpdatePlanes(aCompositor)) {
|
|
return InvalidToWrExternalImage();
|
|
}
|
|
mLocked = true;
|
|
}
|
|
if (aChannelIndex >= mPlanes.size()) {
|
|
return InvalidToWrExternalImage();
|
|
}
|
|
const PlaneInfo& plane = mPlanes[aChannelIndex];
|
|
|
|
const auto uvs = GetUvCoords(plane.mSize);
|
|
|
|
// Prefer native textures, unless our backend forbids it.
|
|
// If the GetUvCoords call above returned anything other than the default,
|
|
// for example if this is a RenderAndroidSurfaceTextureHost, then this won't
|
|
// be handled correctly in the RawDataToWrExternalImage path. But we shouldn't
|
|
// hit this path in practice with a RenderAndroidSurfaceTextureHost.
|
|
layers::TextureHost::NativeTexturePolicy policy =
|
|
layers::TextureHost::BackendNativeTexturePolicy(
|
|
layers::WebRenderBackend::SOFTWARE, plane.mSize);
|
|
return policy == layers::TextureHost::NativeTexturePolicy::FORBID
|
|
? RawDataToWrExternalImage((uint8_t*)plane.mData,
|
|
plane.mStride * plane.mSize.height)
|
|
: NativeTextureToWrExternalImage(plane.mTexture, uvs.first.x,
|
|
uvs.first.y, uvs.second.x,
|
|
uvs.second.y);
|
|
}
|
|
|
|
void RenderTextureHostSWGL::UnlockSWGL() {
|
|
if (mLocked) {
|
|
mLocked = false;
|
|
UnmapPlanes();
|
|
}
|
|
}
|
|
|
|
void RenderTextureHostSWGL::CleanupPlanes() {
|
|
if (!mContext) {
|
|
return;
|
|
}
|
|
if (!mPlanes.empty()) {
|
|
wr_swgl_make_current(mContext);
|
|
for (const auto& plane : mPlanes) {
|
|
wr_swgl_delete_texture(mContext, plane.mTexture);
|
|
}
|
|
mPlanes.clear();
|
|
}
|
|
wr_swgl_destroy_context(mContext);
|
|
mContext = nullptr;
|
|
}
|
|
|
|
RenderTextureHostSWGL::~RenderTextureHostSWGL() { CleanupPlanes(); }
|
|
|
|
bool RenderTextureHostSWGL::LockSWGLCompositeSurface(
|
|
void* aContext, wr::SWGLCompositeSurfaceInfo* aInfo) {
|
|
if (!SetContext(aContext)) {
|
|
return false;
|
|
}
|
|
if (!mLocked) {
|
|
if (!UpdatePlanes(nullptr)) {
|
|
return false;
|
|
}
|
|
mLocked = true;
|
|
}
|
|
MOZ_ASSERT(mPlanes.size() <= 3);
|
|
for (size_t i = 0; i < mPlanes.size(); i++) {
|
|
aInfo->textures[i] = mPlanes[i].mTexture;
|
|
}
|
|
switch (GetFormat()) {
|
|
case gfx::SurfaceFormat::YUV:
|
|
case gfx::SurfaceFormat::NV12:
|
|
case gfx::SurfaceFormat::P010:
|
|
case gfx::SurfaceFormat::YUV422: {
|
|
aInfo->yuv_planes = mPlanes.size();
|
|
auto colorSpace = GetYUVColorSpace();
|
|
aInfo->color_space = ToWrYuvRangedColorSpace(colorSpace);
|
|
auto colorDepth = GetColorDepth();
|
|
aInfo->color_depth = ToWrColorDepth(colorDepth);
|
|
break;
|
|
}
|
|
case gfx::SurfaceFormat::B8G8R8A8:
|
|
case gfx::SurfaceFormat::B8G8R8X8:
|
|
break;
|
|
default:
|
|
gfxCriticalNote << "Unhandled external image format: " << GetFormat();
|
|
MOZ_RELEASE_ASSERT(false, "Unhandled external image format");
|
|
break;
|
|
}
|
|
aInfo->size.width = mPlanes[0].mSize.width;
|
|
aInfo->size.height = mPlanes[0].mSize.height;
|
|
return true;
|
|
}
|
|
|
|
bool wr_swgl_lock_composite_surface(void* aContext, wr::ExternalImageId aId,
|
|
wr::SWGLCompositeSurfaceInfo* aInfo) {
|
|
RenderTextureHost* texture = RenderThread::Get()->GetRenderTexture(aId);
|
|
if (!texture) {
|
|
return false;
|
|
}
|
|
RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL();
|
|
if (!swglTex) {
|
|
return false;
|
|
}
|
|
return swglTex->LockSWGLCompositeSurface(aContext, aInfo);
|
|
}
|
|
|
|
void wr_swgl_unlock_composite_surface(void* aContext, wr::ExternalImageId aId) {
|
|
RenderTextureHost* texture = RenderThread::Get()->GetRenderTexture(aId);
|
|
if (!texture) {
|
|
return;
|
|
}
|
|
RenderTextureHostSWGL* swglTex = texture->AsRenderTextureHostSWGL();
|
|
if (!swglTex) {
|
|
return;
|
|
}
|
|
swglTex->UnlockSWGL();
|
|
}
|
|
|
|
} // namespace wr
|
|
} // namespace mozilla
|