Bug 1395497 - Add AndroidSurfaceTexture support to GLBlitHelper. - r=snorp
MozReview-Commit-ID: JttqOoDCE4O
--- a/gfx/gl/AndroidSurfaceTexture.cpp
+++ b/gfx/gl/AndroidSurfaceTexture.cpp
@@ -3,44 +3,26 @@
#include "AndroidSurfaceTexture.h"
using namespace mozilla;
namespace mozilla {
namespace gl {
void
-AndroidSurfaceTexture::GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture,
- gfx::Matrix4x4& aMatrix)
+AndroidSurfaceTexture::GetTransformMatrix(java::sdk::SurfaceTexture::Param surfaceTexture,
+ gfx::Matrix4x4* outMatrix)
{
JNIEnv* const env = jni::GetEnvForThread();
auto jarray = jni::FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
- aSurfaceTexture->GetTransformMatrix(jarray);
+ surfaceTexture->GetTransformMatrix(jarray);
jfloat* array = env->GetFloatArrayElements(jarray.Get(), nullptr);
- aMatrix._11 = array[0];
- aMatrix._12 = array[1];
- aMatrix._13 = array[2];
- aMatrix._14 = array[3];
-
- aMatrix._21 = array[4];
- aMatrix._22 = array[5];
- aMatrix._23 = array[6];
- aMatrix._24 = array[7];
-
- aMatrix._31 = array[8];
- aMatrix._32 = array[9];
- aMatrix._33 = array[10];
- aMatrix._34 = array[11];
-
- aMatrix._41 = array[12];
- aMatrix._42 = array[13];
- aMatrix._43 = array[14];
- aMatrix._44 = array[15];
+ memcpy(&(outMatrix->_11), array, sizeof(float)*16);
env->ReleaseFloatArrayElements(jarray.Get(), array, 0);
}
} // gl
} // mozilla
#endif // MOZ_WIDGET_ANDROID
--- a/gfx/gl/AndroidSurfaceTexture.h
+++ b/gfx/gl/AndroidSurfaceTexture.h
@@ -13,18 +13,18 @@
typedef uint32_t AndroidSurfaceTextureHandle;
namespace mozilla {
namespace gl {
class AndroidSurfaceTexture {
public:
- static void GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture,
- mozilla::gfx::Matrix4x4& aMatrix);
+ static void GetTransformMatrix(java::sdk::SurfaceTexture::Param surfaceTexture,
+ mozilla::gfx::Matrix4x4* outMatrix);
};
} // gl
} // mozilla
#endif // MOZ_WIDGET_ANDROID
#endif // AndroidSurfaceTexture_h__
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -14,16 +14,17 @@
#include "HeapCopyOfStackArray.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/UniquePtr.h"
#include "GPUVideoImage.h"
#ifdef MOZ_WIDGET_ANDROID
+#include "GeneratedJNIWrappers.h"
#include "AndroidSurfaceTexture.h"
#include "GLImages.h"
#include "GLLibraryEGL.h"
#endif
#ifdef XP_MACOSX
#include "MacIOSurfaceImage.h"
#include "GLContextCGL.h"
@@ -51,17 +52,21 @@ const char* const kFragHeader_Tex2DRect
#define TEXTURE texture \n\
#else \n\
#define TEXTURE texture2DRect \n\
#endif \n\
";
const char* const kFragHeader_TexExt = "\
#extension GL_OES_EGL_image_external : require \n\
#define SAMPLER samplerExternalOES \n\
- #define TEXTURE texture2D \n\
+ #if __VERSION__ >= 130 \n\
+ #define TEXTURE texture \n\
+ #else \n\
+ #define TEXTURE texture2D \n\
+ #endif \n\
";
const char* const kFragBody_RGBA = "\
VARYING vec2 vTexCoord0; \n\
uniform SAMPLER uTex0; \n\
\n\
void main(void) \n\
{ \n\
@@ -710,24 +715,81 @@ GLBlitHelper::BlitImageToFramebuffer(lay
return false;
}
}
// -------------------------------------
#ifdef MOZ_WIDGET_ANDROID
bool
-GLBlitHelper::BlitImage(layers::SurfaceTextureImage* srcImage, const gfx::IntSize&,
- const OriginPos) const
+GLBlitHelper::BlitImage(layers::SurfaceTextureImage* srcImage, const gfx::IntSize& destSize,
+ const OriginPos destOrigin) const
{
- // FIXME
- const auto& srcOrigin = srcImage->GetOriginPos();
- (void)srcOrigin;
- gfxCriticalError() << "BlitImage(SurfaceTextureImage) not implemented.";
- return false;
+ AndroidSurfaceTextureHandle handle = srcImage->GetHandle();
+ const auto& surfaceTexture = java::GeckoSurfaceTexture::Lookup(handle);
+
+ if (!surfaceTexture) {
+ return false;
+ }
+
+ const ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
+
+ if (!surfaceTexture->IsAttachedToGLContext((int64_t)mGL)) {
+ GLuint tex;
+ mGL->MakeCurrent();
+ mGL->fGenTextures(1, &tex);
+
+ if (NS_FAILED(surfaceTexture->AttachToGLContext((int64_t)mGL, tex))) {
+ mGL->fDeleteTextures(1, &tex);
+ return false;
+ }
+ }
+
+ 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 OriginPos 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& prog = GetDrawBlitProg({kFragHeader_TexExt, kFragBody_RGBA});
+ MOZ_RELEASE_ASSERT(prog);
+
+ // 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);
+
+ if (surfaceTexture->IsSingleBuffer()) {
+ surfaceTexture->ReleaseTexImage();
+ }
+
+ return true;
}
#endif
// -------------------------------------
bool
GuessDivisors(const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
gfx::IntSize* const out_divisors)
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -390,17 +390,17 @@ SurfaceTextureSource::IsValid() const
gfx::Matrix4x4
SurfaceTextureSource::GetTextureTransform()
{
MOZ_ASSERT(mSurfTex);
gfx::Matrix4x4 ret;
const auto& surf = java::sdk::SurfaceTexture::LocalRef(java::sdk::SurfaceTexture::Ref::From(mSurfTex));
- AndroidSurfaceTexture::GetTransformMatrix(surf, ret);
+ AndroidSurfaceTexture::GetTransformMatrix(surf, &ret);
return ret;
}
void
SurfaceTextureSource::DeallocateDeviceData()
{
mSurfTex = nullptr;