Bug 1736793 - Add SurfaceTexture support to GLBlitHelper::BlitSdToFramebuffer() r=jgilbert,gfx-reviewers

Blit support of android SurfaceTexture was removed by Bug 1640607.

Differential Revision: https://phabricator.services.mozilla.com/D128992
This commit is contained in:
sotaro 2022-01-19 02:13:48 +00:00
parent 67a8bb6d9c
commit 7a437cab43
7 changed files with 53 additions and 56 deletions

View File

@ -596,6 +596,9 @@ RefPtr<WebGLContext> WebGLContext::Create(HostWebGLContext& host,
if (kIsMacOS) {
types[layers::SurfaceDescriptor::TSurfaceDescriptorMacIOSurface] = true;
}
if (kIsAndroid) {
types[layers::SurfaceDescriptor::TSurfaceTextureDescriptor] = true;
}
return types;
};

View File

@ -7002,6 +7002,7 @@ subsuite = webgl2-core
subsuite = webgl2-core
[generated/test_2_conformance2__textures__misc__npot-video-sizing.html]
subsuite = webgl2-core
fail-if = (os == 'android')
[generated/test_2_conformance2__textures__misc__origin-clean-conformance-offscreencanvas.html]
subsuite = webgl2-core
skip-if = 1

View File

@ -9,6 +9,8 @@
#include "GLContextEGL.h"
#include "GLBlitHelper.h"
#include "GLImages.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/LayersSurfaces.h"
#ifdef MOZ_WIDGET_ANDROID
# include "mozilla/java/GeckoSurfaceTextureNatives.h"
@ -51,23 +53,24 @@ class AndroidSharedBlitGL final {
}
}
void Blit(layers::SurfaceTextureImage* img, const gfx::IntSize& imageSize) {
#ifdef MOZ_WIDGET_ANDROID
void Blit(const java::GeckoSurfaceTexture::Ref& surfaceTexture,
const gfx::IntSize& imageSize) {
StaticMutexAutoLock lock(sMutex);
MOZ_ASSERT(sContext);
// Setting overide also makes conext and surface current.
sContext->SetEGLSurfaceOverride(mTargetSurface);
#ifdef MOZ_WIDGET_ANDROID
sContext->BlitHelper()->BlitImage(img, imageSize, OriginPos::BottomLeft);
#else
MOZ_CRASH("bad platform");
#endif
DebugOnly<bool> rv = sContext->BlitHelper()->Blit(surfaceTexture, imageSize,
OriginPos::TopLeft);
MOZ_ASSERT(rv);
sContext->SwapBuffers();
// This method is called through binder IPC and could run on any thread in
// the pool. Release the context and surface from this thread after use so
// they can be bound to another thread later.
UnmakeCurrent(sContext);
}
#endif
private:
static already_AddRefed<GLContextEGL> CreateContextImpl(bool aUseGles) {
@ -173,9 +176,9 @@ class GLBlitterSupport final
mSize(width, height) {}
void Blit() {
RefPtr<layers::SurfaceTextureImage> img = new layers::SurfaceTextureImage(
mSourceTextureHandle, mSize, false, OriginPos::TopLeft);
mGl->Blit(img, mSize);
auto surfaceTexture =
java::GeckoSurfaceTexture::Lookup(mSourceTextureHandle);
mGl->Blit(surfaceTexture, mSize);
}
private:

View File

@ -23,9 +23,7 @@
#ifdef MOZ_WIDGET_ANDROID
# include "AndroidSurfaceTexture.h"
# include "GLImages.h"
# include "GLLibraryEGL.h"
# include "mozilla/java/GeckoSurfaceTextureWrappers.h"
#endif
#ifdef XP_MACOSX
@ -729,6 +727,13 @@ bool GLBlitHelper::BlitSdToFramebuffer(const layers::SurfaceDescriptor& asd,
}
return BlitImage(surf, destSize, destOrigin);
}
#endif
#ifdef MOZ_WIDGET_ANDROID
case layers::SurfaceDescriptor::TSurfaceTextureDescriptor: {
const auto& sd = asd.get_SurfaceTextureDescriptor();
auto surfaceTexture = java::GeckoSurfaceTexture::Lookup(sd.handle());
return Blit(surfaceTexture, destSize, destOrigin);
}
#endif
default:
return false;
@ -745,15 +750,18 @@ bool GLBlitHelper::BlitImageToFramebuffer(layers::Image* const srcImage,
return BlitPlanarYCbCr(*data, destSize, destOrigin);
}
case ImageFormat::SURFACE_TEXTURE:
case ImageFormat::SURFACE_TEXTURE: {
#ifdef MOZ_WIDGET_ANDROID
return BlitImage(static_cast<layers::SurfaceTextureImage*>(srcImage),
destSize, destOrigin);
auto* image = srcImage->AsSurfaceTextureImage();
MOZ_ASSERT(image);
auto surfaceTexture =
java::GeckoSurfaceTexture::Lookup(image->GetHandle());
return Blit(surfaceTexture, destSize, destOrigin);
#else
MOZ_ASSERT(false);
return false;
#endif
}
case ImageFormat::MAC_IOSURFACE:
#ifdef XP_MACOSX
return BlitImage(srcImage->AsMacIOSurfaceImage(), destSize, destOrigin);
@ -801,12 +809,9 @@ bool GLBlitHelper::BlitImageToFramebuffer(layers::Image* const srcImage,
// -------------------------------------
#ifdef MOZ_WIDGET_ANDROID
bool GLBlitHelper::BlitImage(layers::SurfaceTextureImage* srcImage,
const gfx::IntSize& destSize,
const OriginPos destOrigin) const {
AndroidSurfaceTextureHandle handle = srcImage->GetHandle();
const auto& surfaceTexture = java::GeckoSurfaceTexture::Lookup(handle);
bool GLBlitHelper::Blit(const java::GeckoSurfaceTexture::Ref& surfaceTexture,
const gfx::IntSize& destSize,
const OriginPos destOrigin) const {
if (!surfaceTexture) {
return false;
}
@ -827,38 +832,10 @@ bool GLBlitHelper::BlitImage(layers::SurfaceTextureImage* srcImage,
const ScopedBindTexture savedTex(mGL, surfaceTexture->GetTexName(),
LOCAL_GL_TEXTURE_EXTERNAL);
surfaceTexture->UpdateTexImage();
gfx::Matrix4x4 transform4;
AndroidSurfaceTexture::GetTransformMatrix(
java::sdk::SurfaceTexture::Ref::From(surfaceTexture), &transform4);
Mat3 transform3;
transform3.at(0, 0) = transform4._11;
transform3.at(0, 1) = transform4._12;
transform3.at(0, 2) = transform4._14;
transform3.at(1, 0) = transform4._21;
transform3.at(1, 1) = transform4._22;
transform3.at(1, 2) = transform4._24;
transform3.at(2, 0) = transform4._41;
transform3.at(2, 1) = transform4._42;
transform3.at(2, 2) = transform4._44;
// We don't do w-divison, so if these aren't what we expect, we're probably
// doing something wrong.
MOZ_ASSERT(transform3.at(0, 2) == 0);
MOZ_ASSERT(transform3.at(1, 2) == 0);
MOZ_ASSERT(transform3.at(2, 2) == 1);
const auto& srcOrigin = srcImage->GetOriginPos();
// I honestly have no idea why this logic is flipped, but changing the
// source origin would mean we'd have to flip it in the compositor
// which makes just as little sense as this.
const bool yFlip = (srcOrigin == destOrigin);
const auto transform3 = Mat3::I();
const auto srcOrigin = OriginPos::TopLeft;
const bool yFlip = (srcOrigin != destOrigin);
const auto& prog = GetDrawBlitProg({kFragHeader_TexExt, kFragBody_RGBA});
// There is no padding on these images, so we can use the GetTransformMatrix
// directly.
const DrawBlitProg::BaseArgs baseArgs = {transform3, yFlip, destSize,
Nothing()};
prog->Draw(baseArgs, nullptr);

View File

@ -36,6 +36,10 @@ struct ID3D11Texture2D;
class MacIOSurface;
#endif
#ifdef MOZ_WIDGET_ANDROID
# include "mozilla/java/GeckoSurfaceTextureWrappers.h"
#endif
namespace mozilla {
namespace layers {
@ -54,7 +58,7 @@ class SurfaceDescriptorDXGIYCbCr;
#endif
#ifdef MOZ_WIDGET_ANDROID
class SurfaceTextureImage;
class SurfaceTextureDescriptor;
#endif
#ifdef XP_MACOSX
@ -177,9 +181,8 @@ class GLBlitHelper final {
bool BlitPlanarYCbCr(const layers::PlanarYCbCrData&,
const gfx::IntSize& destSize, OriginPos destOrigin);
#ifdef MOZ_WIDGET_ANDROID
// Blit onto the current FB.
bool BlitImage(layers::SurfaceTextureImage* stImage,
const gfx::IntSize& destSize, OriginPos destOrigin) const;
bool Blit(const java::GeckoSurfaceTexture::Ref& surfaceTexture,
const gfx::IntSize& destSize, const OriginPos destOrigin) const;
#endif
#ifdef XP_MACOSX
bool BlitImage(layers::MacIOSurfaceImage* srcImage,

View File

@ -85,6 +85,14 @@ SurfaceTextureImage::SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
mHasAlpha(aHasAlpha) {
MOZ_ASSERT(mHandle);
}
Maybe<SurfaceDescriptor> SurfaceTextureImage::GetDesc() {
SurfaceDescriptor sd = SurfaceTextureDescriptor(
mHandle, mSize,
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
false /* NOT continuous */, false /* do not ignore transform */);
return Some(sd);
}
#endif
} // namespace layers

View File

@ -59,6 +59,8 @@ class SurfaceTextureImage : public GLImage {
SurfaceTextureImage* AsSurfaceTextureImage() override { return this; }
Maybe<SurfaceDescriptor> GetDesc() override;
void RegisterSetCurrentCallback(UniquePtr<SetCurrentCallback> aCallback) {
mSetCurrentCallback = std::move(aCallback);
}