diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 19f9fd79def7..a0140f503052 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -596,6 +596,9 @@ RefPtr WebGLContext::Create(HostWebGLContext& host, if (kIsMacOS) { types[layers::SurfaceDescriptor::TSurfaceDescriptorMacIOSurface] = true; } + if (kIsAndroid) { + types[layers::SurfaceDescriptor::TSurfaceTextureDescriptor] = true; + } return types; }; diff --git a/dom/canvas/test/webgl-conf/generated-mochitest.ini b/dom/canvas/test/webgl-conf/generated-mochitest.ini index d5da0f011b2d..c37f4a7fe3fe 100644 --- a/dom/canvas/test/webgl-conf/generated-mochitest.ini +++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini @@ -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 diff --git a/gfx/gl/AndroidSurfaceTexture.cpp b/gfx/gl/AndroidSurfaceTexture.cpp index 1267b892772a..9ccbd71360b5 100644 --- a/gfx/gl/AndroidSurfaceTexture.cpp +++ b/gfx/gl/AndroidSurfaceTexture.cpp @@ -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 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 CreateContextImpl(bool aUseGles) { @@ -173,9 +176,9 @@ class GLBlitterSupport final mSize(width, height) {} void Blit() { - RefPtr img = new layers::SurfaceTextureImage( - mSourceTextureHandle, mSize, false, OriginPos::TopLeft); - mGl->Blit(img, mSize); + auto surfaceTexture = + java::GeckoSurfaceTexture::Lookup(mSourceTextureHandle); + mGl->Blit(surfaceTexture, mSize); } private: diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index 6801c9df7eb6..e76a685d28d1 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -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(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); diff --git a/gfx/gl/GLBlitHelper.h b/gfx/gl/GLBlitHelper.h index 748149b383ea..4d916289c311 100644 --- a/gfx/gl/GLBlitHelper.h +++ b/gfx/gl/GLBlitHelper.h @@ -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, diff --git a/gfx/layers/GLImages.cpp b/gfx/layers/GLImages.cpp index daec5f651987..64b2988a2c39 100644 --- a/gfx/layers/GLImages.cpp +++ b/gfx/layers/GLImages.cpp @@ -85,6 +85,14 @@ SurfaceTextureImage::SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle, mHasAlpha(aHasAlpha) { MOZ_ASSERT(mHandle); } + +Maybe 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 diff --git a/gfx/layers/GLImages.h b/gfx/layers/GLImages.h index f82f3219ed47..806159a8fa3a 100644 --- a/gfx/layers/GLImages.h +++ b/gfx/layers/GLImages.h @@ -59,6 +59,8 @@ class SurfaceTextureImage : public GLImage { SurfaceTextureImage* AsSurfaceTextureImage() override { return this; } + Maybe GetDesc() override; + void RegisterSetCurrentCallback(UniquePtr aCallback) { mSetCurrentCallback = std::move(aCallback); }