зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1486659 - p2: expose native GL blitter to Java. r=snorp
Differential Revision: https://phabricator.services.mozilla.com/D11938 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a1926ace73
Коммит
82531b5e45
|
@ -8,6 +8,13 @@
|
|||
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
|
||||
#include "GeneratedJNINatives.h"
|
||||
|
||||
#include "AndroidNativeWindow.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLImages.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -28,6 +35,149 @@ void AndroidSurfaceTexture::GetTransformMatrix(
|
|||
env->ReleaseFloatArrayElements(jarray.Get(), array, 0);
|
||||
}
|
||||
|
||||
class SharedGL {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedGL);
|
||||
|
||||
SharedGL(AndroidNativeWindow& window) {
|
||||
MutexAutoLock lock(sMutex);
|
||||
|
||||
if (!sContext) {
|
||||
MOZ_ASSERT(sInstanceCount == 0);
|
||||
sContext = CreateContext();
|
||||
if (!sContext) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
InitSurface(window);
|
||||
++sInstanceCount;
|
||||
}
|
||||
|
||||
void Blit(const AndroidSurfaceTextureHandle& sourceTextureHandle,
|
||||
const gfx::IntSize& imageSize) {
|
||||
MutexAutoLock lock(sMutex);
|
||||
MOZ_ASSERT(sContext);
|
||||
|
||||
// Setting overide also makes conext and surface current.
|
||||
sContext->SetEGLSurfaceOverride(mTargetSurface);
|
||||
RefPtr<layers::SurfaceTextureImage> img = new layers::SurfaceTextureImage(
|
||||
sourceTextureHandle, imageSize, false, OriginPos::TopLeft);
|
||||
sContext->BlitHelper()->BlitImage(img, imageSize, OriginPos::BottomLeft);
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
~SharedGL() {
|
||||
MutexAutoLock lock(sMutex);
|
||||
|
||||
if (mTargetSurface != EGL_NO_SURFACE) {
|
||||
GLLibraryEGL::Get()->fDestroySurface(EGL_DISPLAY(), mTargetSurface);
|
||||
}
|
||||
|
||||
// Destroy shared GL context when no one uses it.
|
||||
if (--sInstanceCount == 0) {
|
||||
sContext = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContextEGL> CreateContext() {
|
||||
sMutex.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(!sContext);
|
||||
|
||||
auto* egl = gl::GLLibraryEGL::Get();
|
||||
EGLDisplay eglDisplay = egl->fGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
EGLConfig eglConfig;
|
||||
CreateConfig(&eglConfig, /* bpp */ 24, /* depth buffer? */ false);
|
||||
EGLint attributes[] = {LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2, LOCAL_EGL_NONE};
|
||||
EGLContext eglContext =
|
||||
egl->fCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attributes);
|
||||
RefPtr<GLContextEGL> gl = new GLContextEGL(
|
||||
CreateContextFlags::NONE, SurfaceCaps::Any(),
|
||||
/* offscreen? */ false, eglConfig, EGL_NO_SURFACE, eglContext);
|
||||
if (!gl->Init()) {
|
||||
NS_WARNING("Fail to create GL context for native blitter.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Yield the current state made in constructor.
|
||||
UnmakeCurrent(gl);
|
||||
return gl.forget();
|
||||
}
|
||||
|
||||
void InitSurface(AndroidNativeWindow& window) {
|
||||
sMutex.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(sContext);
|
||||
|
||||
mTargetSurface = gl::GLLibraryEGL::Get()->fCreateWindowSurface(
|
||||
sContext->GetEGLDisplay(), sContext->mConfig, window.NativeWindow(), 0);
|
||||
}
|
||||
|
||||
static bool UnmakeCurrent(RefPtr<GLContextEGL>& gl) {
|
||||
sMutex.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(gl);
|
||||
|
||||
if (!gl->IsCurrent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return gl::GLLibraryEGL::Get()->fMakeCurrent(
|
||||
EGL_DISPLAY(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static Mutex sMutex;
|
||||
static RefPtr<GLContextEGL> sContext;
|
||||
static size_t sInstanceCount;
|
||||
|
||||
EGLSurface mTargetSurface;
|
||||
};
|
||||
|
||||
Mutex SharedGL::sMutex("SharedGLContext::sMutex");
|
||||
RefPtr<GLContextEGL> SharedGL::sContext(nullptr);
|
||||
size_t SharedGL::sInstanceCount = 0;
|
||||
|
||||
class GLBlitterSupport final
|
||||
: public java::GeckoSurfaceTexture::NativeGLBlitHelper::Natives<
|
||||
GLBlitterSupport> {
|
||||
public:
|
||||
using Base =
|
||||
java::GeckoSurfaceTexture::NativeGLBlitHelper::Natives<GLBlitterSupport>;
|
||||
using Base::AttachNative;
|
||||
using Base::DisposeNative;
|
||||
using Base::GetNative;
|
||||
|
||||
static java::GeckoSurfaceTexture::NativeGLBlitHelper::LocalRef Create(
|
||||
jint sourceTextureHandle, jni::Object::Param targetSurface, jint width,
|
||||
jint height) {
|
||||
AndroidNativeWindow win(java::GeckoSurface::Ref::From(targetSurface));
|
||||
auto helper = java::GeckoSurfaceTexture::NativeGLBlitHelper::New();
|
||||
RefPtr<SharedGL> gl = new SharedGL(win);
|
||||
GLBlitterSupport::AttachNative(
|
||||
helper, MakeUnique<GLBlitterSupport>(std::move(gl), sourceTextureHandle,
|
||||
width, height));
|
||||
return helper;
|
||||
}
|
||||
|
||||
GLBlitterSupport(RefPtr<SharedGL>&& gl, jint sourceTextureHandle, jint width,
|
||||
jint height)
|
||||
: mGl(gl),
|
||||
mSourceTextureHandle(sourceTextureHandle),
|
||||
mSize(width, height) {}
|
||||
|
||||
void Blit() { mGl->Blit(mSourceTextureHandle, mSize); }
|
||||
|
||||
private:
|
||||
const RefPtr<SharedGL> mGl;
|
||||
const AndroidSurfaceTextureHandle mSourceTextureHandle;
|
||||
const gfx::IntSize mSize;
|
||||
};
|
||||
|
||||
void AndroidSurfaceTexture::Init() { GLBlitterSupport::Init(); }
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mozilla
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace gl {
|
|||
|
||||
class AndroidSurfaceTexture {
|
||||
public:
|
||||
static void Init();
|
||||
static void GetTransformMatrix(
|
||||
java::sdk::SurfaceTexture::Param surfaceTexture,
|
||||
mozilla::gfx::Matrix4x4* outMatrix);
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.HashMap;
|
|||
import java.util.LinkedList;
|
||||
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.mozglue.JNIObject;
|
||||
|
||||
/* package */ final class GeckoSurfaceTexture extends SurfaceTexture {
|
||||
private static final String LOGTAG = "GeckoSurfaceTexture";
|
||||
|
@ -36,6 +37,8 @@ import org.mozilla.gecko.annotation.WrapForJNI;
|
|||
private AtomicInteger mUseCount;
|
||||
private boolean mFinalized;
|
||||
|
||||
private NativeGLBlitHelper mBlitter;
|
||||
|
||||
private GeckoSurfaceTexture(int handle) {
|
||||
super(0);
|
||||
init(handle, false);
|
||||
|
@ -122,6 +125,9 @@ import org.mozilla.gecko.annotation.WrapForJNI;
|
|||
|
||||
@Override
|
||||
public synchronized void release() {
|
||||
if (mBlitter != null) {
|
||||
mBlitter.disposeNative();
|
||||
}
|
||||
try {
|
||||
super.release();
|
||||
synchronized (sSurfaceTextures) {
|
||||
|
@ -276,8 +282,28 @@ import org.mozilla.gecko.annotation.WrapForJNI;
|
|||
}
|
||||
}
|
||||
|
||||
/* package */ synchronized void configureSnapshot(GeckoSurface target, int width, int height) {
|
||||
mBlitter = NativeGLBlitHelper.create(mHandle, target, width, height);
|
||||
}
|
||||
|
||||
/* package */ synchronized void takeSnapshot() {
|
||||
mBlitter.blit();
|
||||
}
|
||||
|
||||
public interface Callbacks {
|
||||
void onUpdateTexImage();
|
||||
void onReleaseTexImage();
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public static class NativeGLBlitHelper extends JNIObject {
|
||||
public native static NativeGLBlitHelper create(int textureHandle,
|
||||
GeckoSurface targetSurface,
|
||||
int width,
|
||||
int height);
|
||||
public native void blit();
|
||||
|
||||
@Override
|
||||
protected native void disposeNative();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include "AndroidBridge.h"
|
||||
#include "AndroidBridgeUtilities.h"
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#include "GeneratedJNINatives.h"
|
||||
#include <android/log.h>
|
||||
#include <pthread.h>
|
||||
|
@ -411,6 +412,7 @@ nsAppShell::nsAppShell()
|
|||
mozilla::widget::Telemetry::Init();
|
||||
mozilla::widget::WebExecutorSupport::Init();
|
||||
nsWindow::InitNatives();
|
||||
mozilla::gl::AndroidSurfaceTexture::Init();
|
||||
|
||||
if (jni::IsFennec()) {
|
||||
BrowserLocaleManagerSupport::Init();
|
||||
|
|
Загрузка…
Ссылка в новой задаче