mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 10:08:41 +00:00
Bug 942505 - Move everything SharedHandle-related out of GLContext - r=jgilbert
This commit is contained in:
parent
6f935c23a0
commit
41b5c423b1
@ -54,6 +54,7 @@ using namespace mozilla;
|
|||||||
#include "GLContextProvider.h"
|
#include "GLContextProvider.h"
|
||||||
#include "GLContext.h"
|
#include "GLContext.h"
|
||||||
#include "TexturePoolOGL.h"
|
#include "TexturePoolOGL.h"
|
||||||
|
#include "GLSharedHandleHelpers.h"
|
||||||
|
|
||||||
using namespace mozilla::gl;
|
using namespace mozilla::gl;
|
||||||
|
|
||||||
@ -138,9 +139,10 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SharedTextureHandle handle =
|
SharedTextureHandle handle =
|
||||||
sPluginContext->CreateSharedHandle(gl::SameProcess,
|
gl::CreateSharedHandle(sPluginContext,
|
||||||
(void*)mTextureInfo.mTexture,
|
gl::SameProcess,
|
||||||
gl::TextureID);
|
(void*)mTextureInfo.mTexture,
|
||||||
|
gl::TextureID);
|
||||||
|
|
||||||
// We want forget about this now, so delete the texture. Assigning it to zero
|
// We want forget about this now, so delete the texture. Assigning it to zero
|
||||||
// ensures that we create a new one in Lock()
|
// ensures that we create a new one in Lock()
|
||||||
@ -1018,9 +1020,10 @@ SharedTextureHandle nsNPAPIPluginInstance::CreateSharedHandle()
|
|||||||
return mContentTexture->CreateSharedHandle();
|
return mContentTexture->CreateSharedHandle();
|
||||||
} else if (mContentSurface) {
|
} else if (mContentSurface) {
|
||||||
EnsureGLContext();
|
EnsureGLContext();
|
||||||
return sPluginContext->CreateSharedHandle(gl::SameProcess,
|
return gl::CreateSharedHandle(sPluginContext,
|
||||||
mContentSurface,
|
gl::SameProcess,
|
||||||
gl::SurfaceTexture);
|
mContentSurface,
|
||||||
|
gl::SurfaceTexture);
|
||||||
} else return 0;
|
} else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ using mozilla::DefaultXDisplay;
|
|||||||
#include "ImageContainer.h"
|
#include "ImageContainer.h"
|
||||||
#include "nsIDOMHTMLCollection.h"
|
#include "nsIDOMHTMLCollection.h"
|
||||||
#include "GLContext.h"
|
#include "GLContext.h"
|
||||||
|
#include "GLSharedHandleHelpers.h"
|
||||||
#include "nsIContentInlines.h"
|
#include "nsIContentInlines.h"
|
||||||
#include "mozilla/MiscEvents.h"
|
#include "mozilla/MiscEvents.h"
|
||||||
#include "mozilla/MouseEvents.h"
|
#include "mozilla/MouseEvents.h"
|
||||||
@ -1508,9 +1509,10 @@ already_AddRefed<ImageContainer> nsPluginInstanceOwner::GetImageContainerForVide
|
|||||||
SharedTextureImage::Data data;
|
SharedTextureImage::Data data;
|
||||||
|
|
||||||
data.mShareType = gl::SameProcess;
|
data.mShareType = gl::SameProcess;
|
||||||
data.mHandle = mInstance->GLContext()->CreateSharedHandle(data.mShareType,
|
data.mHandle = gl::CreateSharedHandle(mInstance->GLContext(),
|
||||||
aVideoInfo->mSurfaceTexture,
|
data.mShareType,
|
||||||
gl::SurfaceTexture);
|
aVideoInfo->mSurfaceTexture,
|
||||||
|
gl::SurfaceTexture);
|
||||||
|
|
||||||
// The logic below for Honeycomb is just a guess, but seems to work. We don't have a separate
|
// The logic below for Honeycomb is just a guess, but seems to work. We don't have a separate
|
||||||
// inverted flag for video.
|
// inverted flag for video.
|
||||||
|
@ -2549,71 +2549,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
const gfxIntSize& OffscreenSize() const;
|
const gfxIntSize& OffscreenSize() const;
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new shared GLContext content handle, using the passed buffer as a source.
|
|
||||||
* Must be released by ReleaseSharedHandle. UpdateSharedHandle will have no effect
|
|
||||||
* on handles created with this method, as the caller owns the source (the passed buffer)
|
|
||||||
* and is responsible for updating it accordingly.
|
|
||||||
*/
|
|
||||||
virtual SharedTextureHandle CreateSharedHandle(SharedTextureShareType shareType,
|
|
||||||
void* buffer,
|
|
||||||
SharedTextureBufferType bufferType)
|
|
||||||
{ return 0; }
|
|
||||||
/**
|
|
||||||
* Publish GLContext content to intermediate buffer attached to shared handle.
|
|
||||||
* Shared handle content is ready to be used after call returns, and no need extra Flush/Finish are required.
|
|
||||||
* GLContext must be current before this call
|
|
||||||
*/
|
|
||||||
virtual void UpdateSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle)
|
|
||||||
{ }
|
|
||||||
/**
|
|
||||||
* - It is better to call ReleaseSharedHandle before original GLContext destroyed,
|
|
||||||
* otherwise warning will be thrown on attempt to destroy Texture associated with SharedHandle, depends on backend implementation.
|
|
||||||
* - It does not require to be called on context where it was created,
|
|
||||||
* because SharedHandle suppose to keep Context reference internally,
|
|
||||||
* or don't require specific context at all, for example IPC SharedHandle.
|
|
||||||
* - Not recommended to call this between AttachSharedHandle and Draw Target call.
|
|
||||||
* if it is really required for some special backend, then DetachSharedHandle API must be added with related implementation.
|
|
||||||
* - It is recommended to stop any possible access to SharedHandle (Attachments, pending GL calls) before calling Release,
|
|
||||||
* otherwise some artifacts might appear or even crash if API backend implementation does not expect that.
|
|
||||||
* SharedHandle (currently EGLImage) does not require GLContext because it is EGL call, and can be destroyed
|
|
||||||
* at any time, unless EGLImage have siblings (which are not expected with current API).
|
|
||||||
*/
|
|
||||||
virtual void ReleaseSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GLenum mTarget;
|
|
||||||
SurfaceFormat mTextureFormat;
|
|
||||||
gfx3DMatrix mTextureTransform;
|
|
||||||
} SharedHandleDetails;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns information necessary for rendering a shared handle.
|
|
||||||
* These values change depending on what sharing mechanism is in use
|
|
||||||
*/
|
|
||||||
virtual bool GetSharedHandleDetails(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle,
|
|
||||||
SharedHandleDetails& details)
|
|
||||||
{ return false; }
|
|
||||||
/**
|
|
||||||
* Attach Shared GL Handle to GL_TEXTURE_2D target
|
|
||||||
* GLContext must be current before this call
|
|
||||||
*/
|
|
||||||
virtual bool AttachSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle)
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detach Shared GL Handle from GL_TEXTURE_2D target
|
|
||||||
*/
|
|
||||||
virtual void DetachSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void BindFB(GLuint fb) {
|
void BindFB(GLuint fb) {
|
||||||
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
|
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
|
||||||
MOZ_ASSERT(!fb || fIsFramebuffer(fb));
|
MOZ_ASSERT(!fb || fIsFramebuffer(fb));
|
||||||
|
@ -271,7 +271,6 @@ public:
|
|||||||
, mIsDoubleBuffered(false)
|
, mIsDoubleBuffered(false)
|
||||||
, mCanBindToTexture(false)
|
, mCanBindToTexture(false)
|
||||||
, mShareWithEGLImage(false)
|
, mShareWithEGLImage(false)
|
||||||
, mTemporaryEGLImageTexture(0)
|
|
||||||
{
|
{
|
||||||
// any EGL contexts will always be GLESv2
|
// any EGL contexts will always be GLESv2
|
||||||
SetProfileVersion(ContextProfile::OpenGLES, 200);
|
SetProfileVersion(ContextProfile::OpenGLES, 200);
|
||||||
@ -294,13 +293,6 @@ public:
|
|||||||
|
|
||||||
~GLContextEGL()
|
~GLContextEGL()
|
||||||
{
|
{
|
||||||
if (MakeCurrent()) {
|
|
||||||
if (mTemporaryEGLImageTexture != 0) {
|
|
||||||
fDeleteTextures(1, &mTemporaryEGLImageTexture);
|
|
||||||
mTemporaryEGLImageTexture = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MarkDestroyed();
|
MarkDestroyed();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -577,19 +569,6 @@ public:
|
|||||||
static already_AddRefed<GLContextEGL>
|
static already_AddRefed<GLContextEGL>
|
||||||
CreateEGLPBufferOffscreenContext(const gfxIntSize& size);
|
CreateEGLPBufferOffscreenContext(const gfxIntSize& size);
|
||||||
|
|
||||||
virtual SharedTextureHandle CreateSharedHandle(SharedTextureShareType shareType,
|
|
||||||
void* buffer,
|
|
||||||
SharedTextureBufferType bufferType);
|
|
||||||
virtual void UpdateSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle);
|
|
||||||
virtual void ReleaseSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle);
|
|
||||||
virtual bool GetSharedHandleDetails(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle,
|
|
||||||
SharedHandleDetails& details);
|
|
||||||
virtual bool AttachSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class GLContextProviderEGL;
|
friend class GLContextProviderEGL;
|
||||||
|
|
||||||
@ -608,10 +587,6 @@ protected:
|
|||||||
nsRefPtr<HwcComposer2D> mHwc;
|
nsRefPtr<HwcComposer2D> mHwc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// A dummy texture ID that can be used when we need a texture object whose
|
|
||||||
// images we're going to define with EGLImageTargetTexture2D.
|
|
||||||
GLuint mTemporaryEGLImageTexture;
|
|
||||||
|
|
||||||
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
|
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
|
||||||
EGLenum bindToTextureFormat,
|
EGLenum bindToTextureFormat,
|
||||||
gfxIntSize& pbsize)
|
gfxIntSize& pbsize)
|
||||||
@ -656,319 +631,6 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum SharedHandleType {
|
|
||||||
SharedHandleType_Image
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
, SharedHandleType_SurfaceTexture
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class SharedTextureHandleWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SharedTextureHandleWrapper(SharedHandleType aHandleType) : mHandleType(aHandleType)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~SharedTextureHandleWrapper()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedHandleType Type() { return mHandleType; }
|
|
||||||
|
|
||||||
SharedHandleType mHandleType;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
class SurfaceTextureWrapper: public SharedTextureHandleWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SurfaceTextureWrapper(nsSurfaceTexture* aSurfaceTexture) :
|
|
||||||
SharedTextureHandleWrapper(SharedHandleType_SurfaceTexture)
|
|
||||||
, mSurfaceTexture(aSurfaceTexture)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~SurfaceTextureWrapper() {
|
|
||||||
mSurfaceTexture = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsSurfaceTexture* SurfaceTexture() { return mSurfaceTexture; }
|
|
||||||
|
|
||||||
nsRefPtr<nsSurfaceTexture> mSurfaceTexture;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
class EGLTextureWrapper : public SharedTextureHandleWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EGLTextureWrapper() :
|
|
||||||
SharedTextureHandleWrapper(SharedHandleType_Image)
|
|
||||||
, mEGLImage(nullptr)
|
|
||||||
, mSyncObject(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Args are the active GL context, and a texture in that GL
|
|
||||||
// context for which to create an EGLImage. After the EGLImage
|
|
||||||
// is created, the texture is unused by EGLTextureWrapper.
|
|
||||||
bool CreateEGLImage(GLContextEGL *ctx, GLuint texture) {
|
|
||||||
MOZ_ASSERT(!mEGLImage && texture && sEGLLibrary.HasKHRImageBase());
|
|
||||||
static const EGLint eglAttributes[] = {
|
|
||||||
LOCAL_EGL_NONE
|
|
||||||
};
|
|
||||||
EGLContext eglContext = (EGLContext)ctx->GetEGLContext();
|
|
||||||
mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext, LOCAL_EGL_GL_TEXTURE_2D,
|
|
||||||
(EGLClientBuffer)texture, eglAttributes);
|
|
||||||
if (!mEGLImage) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", sEGLLibrary.fGetError());
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~EGLTextureWrapper() {
|
|
||||||
if (mEGLImage) {
|
|
||||||
sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mEGLImage);
|
|
||||||
mEGLImage = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const EGLImage GetEGLImage() {
|
|
||||||
return mEGLImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert a sync point on the given context, which should be the current active
|
|
||||||
// context.
|
|
||||||
bool MakeSync(GLContext *ctx) {
|
|
||||||
MOZ_ASSERT(mSyncObject == nullptr);
|
|
||||||
|
|
||||||
if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) {
|
|
||||||
mSyncObject = sEGLLibrary.fCreateSync(EGL_DISPLAY(), LOCAL_EGL_SYNC_FENCE, nullptr);
|
|
||||||
// We need to flush to make sure the sync object enters the command stream;
|
|
||||||
// we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait
|
|
||||||
// happens on a different thread/context.
|
|
||||||
ctx->fFlush();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSyncObject == EGL_NO_SYNC) {
|
|
||||||
// we failed to create one, so just do a finish
|
|
||||||
ctx->fFinish();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WaitSync() {
|
|
||||||
if (!mSyncObject) {
|
|
||||||
// if we have no sync object, then we did a Finish() earlier
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait at most 1 second; this should really be never/rarely hit
|
|
||||||
const uint64_t ns_per_ms = 1000 * 1000;
|
|
||||||
EGLTime timeout = 1000 * ns_per_ms;
|
|
||||||
|
|
||||||
EGLint result = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSyncObject, 0, timeout);
|
|
||||||
sEGLLibrary.fDestroySync(EGL_DISPLAY(), mSyncObject);
|
|
||||||
mSyncObject = nullptr;
|
|
||||||
|
|
||||||
return result == LOCAL_EGL_CONDITION_SATISFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
EGLImage mEGLImage;
|
|
||||||
EGLSync mSyncObject;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
GLContextEGL::UpdateSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle)
|
|
||||||
{
|
|
||||||
if (shareType != SameProcess) {
|
|
||||||
NS_ERROR("Implementation not available for this sharing type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(sharedHandle);
|
|
||||||
|
|
||||||
NS_ASSERTION(wrapper->Type() == SharedHandleType_Image, "Expected EGLImage shared handle");
|
|
||||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
|
||||||
|
|
||||||
EGLTextureWrapper* wrap = reinterpret_cast<EGLTextureWrapper*>(wrapper);
|
|
||||||
// We need to copy the current GLContext drawing buffer to the texture
|
|
||||||
// exported by the EGLImage. Need to save both the read FBO and the texture
|
|
||||||
// binding, because we're going to munge them to do this.
|
|
||||||
ScopedBindTexture autoTex(this, mTemporaryEGLImageTexture);
|
|
||||||
fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
|
|
||||||
|
|
||||||
// CopyTexSubImage2D, is ~2x slower than simple FBO render to texture with
|
|
||||||
// draw quads, but if we want that, we need to assure that our default
|
|
||||||
// framebuffer is texture-backed.
|
|
||||||
gfxIntSize size = OffscreenSize();
|
|
||||||
BlitHelper()->BlitFramebufferToTexture(0, mTemporaryEGLImageTexture, size, size);
|
|
||||||
|
|
||||||
// Make sure our copy is finished, so that we can be ready to draw
|
|
||||||
// in different thread GLContext. If we have KHR_fence_sync, then
|
|
||||||
// we insert a sync object, otherwise we have to do a GuaranteeResolve.
|
|
||||||
wrap->MakeSync(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedTextureHandle
|
|
||||||
GLContextEGL::CreateSharedHandle(SharedTextureShareType shareType,
|
|
||||||
void* buffer,
|
|
||||||
SharedTextureBufferType bufferType)
|
|
||||||
{
|
|
||||||
// Both EGLImage and SurfaceTexture only support same-process currently, but
|
|
||||||
// it's possible to make SurfaceTexture work across processes. We should do that.
|
|
||||||
if (shareType != SameProcess)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (bufferType) {
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
case SharedTextureBufferType::SurfaceTexture:
|
|
||||||
if (!IsExtensionSupported(GLContext::OES_EGL_image_external)) {
|
|
||||||
NS_WARNING("Missing GL_OES_EGL_image_external");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (SharedTextureHandle) new SurfaceTextureWrapper(reinterpret_cast<nsSurfaceTexture*>(buffer));
|
|
||||||
#endif
|
|
||||||
case SharedTextureBufferType::TextureID: {
|
|
||||||
if (!mShareWithEGLImage)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
GLuint texture = (uintptr_t)buffer;
|
|
||||||
EGLTextureWrapper* tex = new EGLTextureWrapper();
|
|
||||||
if (!tex->CreateEGLImage(this, texture)) {
|
|
||||||
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
|
||||||
delete tex;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (SharedTextureHandle)tex;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
NS_ERROR("Unknown shared texture buffer type");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLContextEGL::ReleaseSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle)
|
|
||||||
{
|
|
||||||
if (shareType != SameProcess) {
|
|
||||||
NS_ERROR("Implementation not available for this sharing type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(sharedHandle);
|
|
||||||
|
|
||||||
switch (wrapper->Type()) {
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
case SharedHandleType_SurfaceTexture:
|
|
||||||
delete wrapper;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case SharedHandleType_Image: {
|
|
||||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
|
||||||
|
|
||||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle;
|
|
||||||
delete wrap;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
NS_ERROR("Unknown shared handle type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLContextEGL::GetSharedHandleDetails(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle,
|
|
||||||
SharedHandleDetails& details)
|
|
||||||
{
|
|
||||||
if (shareType != SameProcess)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(sharedHandle);
|
|
||||||
|
|
||||||
switch (wrapper->Type()) {
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
case SharedHandleType_SurfaceTexture: {
|
|
||||||
SurfaceTextureWrapper* surfaceWrapper = reinterpret_cast<SurfaceTextureWrapper*>(wrapper);
|
|
||||||
|
|
||||||
details.mTarget = LOCAL_GL_TEXTURE_EXTERNAL;
|
|
||||||
details.mTextureFormat = FORMAT_R8G8B8A8;
|
|
||||||
surfaceWrapper->SurfaceTexture()->GetTransformMatrix(details.mTextureTransform);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case SharedHandleType_Image:
|
|
||||||
details.mTarget = LOCAL_GL_TEXTURE_2D;
|
|
||||||
details.mTextureFormat = FORMAT_R8G8B8A8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
NS_ERROR("Unknown shared handle type");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLContextEGL::AttachSharedHandle(SharedTextureShareType shareType,
|
|
||||||
SharedTextureHandle sharedHandle)
|
|
||||||
{
|
|
||||||
if (shareType != SameProcess)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(sharedHandle);
|
|
||||||
|
|
||||||
switch (wrapper->Type()) {
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
case SharedHandleType_SurfaceTexture: {
|
|
||||||
#ifndef DEBUG
|
|
||||||
/**
|
|
||||||
* NOTE: SurfaceTexture spams us if there are any existing GL errors, so we'll clear
|
|
||||||
* them here in order to avoid that.
|
|
||||||
*/
|
|
||||||
GetAndClearError();
|
|
||||||
#endif
|
|
||||||
SurfaceTextureWrapper* surfaceTextureWrapper = reinterpret_cast<SurfaceTextureWrapper*>(wrapper);
|
|
||||||
|
|
||||||
// FIXME: SurfaceTexture provides a transform matrix which is supposed to
|
|
||||||
// be applied to the texture coordinates. We should return that here
|
|
||||||
// so we can render correctly. Bug 775083
|
|
||||||
surfaceTextureWrapper->SurfaceTexture()->UpdateTexImage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif // MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
case SharedHandleType_Image: {
|
|
||||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
|
||||||
|
|
||||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle;
|
|
||||||
wrap->WaitSync();
|
|
||||||
fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
NS_ERROR("Unknown shared handle type");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
|
GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
|
||||||
{
|
{
|
||||||
|
328
gfx/gl/GLSharedHandleHelpers.cpp
Normal file
328
gfx/gl/GLSharedHandleHelpers.cpp
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/* 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 "GLContext.h"
|
||||||
|
#include "GLLibraryEGL.h"
|
||||||
|
#include "GLSharedHandleHelpers.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
enum SharedHandleType {
|
||||||
|
SharedHandleType_Image
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
, SharedHandleType_SurfaceTexture
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class SharedTextureHandleWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SharedTextureHandleWrapper(SharedHandleType aHandleType) : mHandleType(aHandleType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~SharedTextureHandleWrapper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedHandleType Type() { return mHandleType; }
|
||||||
|
|
||||||
|
SharedHandleType mHandleType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
|
||||||
|
class SurfaceTextureWrapper: public SharedTextureHandleWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SurfaceTextureWrapper(nsSurfaceTexture* aSurfaceTexture) :
|
||||||
|
SharedTextureHandleWrapper(SharedHandleType_SurfaceTexture)
|
||||||
|
, mSurfaceTexture(aSurfaceTexture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~SurfaceTextureWrapper() {
|
||||||
|
mSurfaceTexture = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsSurfaceTexture* SurfaceTexture() { return mSurfaceTexture; }
|
||||||
|
|
||||||
|
nsRefPtr<nsSurfaceTexture> mSurfaceTexture;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MOZ_WIDGET_ANDROID
|
||||||
|
|
||||||
|
class EGLTextureWrapper : public SharedTextureHandleWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EGLTextureWrapper() :
|
||||||
|
SharedTextureHandleWrapper(SharedHandleType_Image)
|
||||||
|
, mEGLImage(nullptr)
|
||||||
|
, mSyncObject(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args are the active GL context, and a texture in that GL
|
||||||
|
// context for which to create an EGLImage. After the EGLImage
|
||||||
|
// is created, the texture is unused by EGLTextureWrapper.
|
||||||
|
bool CreateEGLImage(GLContext *ctx, uintptr_t texture) {
|
||||||
|
MOZ_ASSERT(!mEGLImage && texture && sEGLLibrary.HasKHRImageBase());
|
||||||
|
static const EGLint eglAttributes[] = {
|
||||||
|
LOCAL_EGL_NONE
|
||||||
|
};
|
||||||
|
EGLContext eglContext = (EGLContext)ctx->GetNativeData(GLContext::NativeGLContext);
|
||||||
|
mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext, LOCAL_EGL_GL_TEXTURE_2D,
|
||||||
|
(EGLClientBuffer)texture, eglAttributes);
|
||||||
|
if (!mEGLImage) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", sEGLLibrary.fGetError());
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~EGLTextureWrapper() {
|
||||||
|
if (mEGLImage) {
|
||||||
|
sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mEGLImage);
|
||||||
|
mEGLImage = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const EGLImage GetEGLImage() {
|
||||||
|
return mEGLImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert a sync point on the given context, which should be the current active
|
||||||
|
// context.
|
||||||
|
bool MakeSync(GLContext *ctx) {
|
||||||
|
MOZ_ASSERT(mSyncObject == nullptr);
|
||||||
|
|
||||||
|
if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) {
|
||||||
|
mSyncObject = sEGLLibrary.fCreateSync(EGL_DISPLAY(), LOCAL_EGL_SYNC_FENCE, nullptr);
|
||||||
|
// We need to flush to make sure the sync object enters the command stream;
|
||||||
|
// we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait
|
||||||
|
// happens on a different thread/context.
|
||||||
|
ctx->fFlush();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSyncObject == EGL_NO_SYNC) {
|
||||||
|
// we failed to create one, so just do a finish
|
||||||
|
ctx->fFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitSync() {
|
||||||
|
if (!mSyncObject) {
|
||||||
|
// if we have no sync object, then we did a Finish() earlier
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait at most 1 second; this should really be never/rarely hit
|
||||||
|
const uint64_t ns_per_ms = 1000 * 1000;
|
||||||
|
EGLTime timeout = 1000 * ns_per_ms;
|
||||||
|
|
||||||
|
EGLint result = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSyncObject, 0, timeout);
|
||||||
|
sEGLLibrary.fDestroySync(EGL_DISPLAY(), mSyncObject);
|
||||||
|
mSyncObject = nullptr;
|
||||||
|
|
||||||
|
return result == LOCAL_EGL_CONDITION_SATISFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EGLImage mEGLImage;
|
||||||
|
EGLSync mSyncObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool DoesEGLContextSupportSharingWithEGLImage(GLContext *gl)
|
||||||
|
{
|
||||||
|
return sEGLLibrary.HasKHRImageBase() &&
|
||||||
|
sEGLLibrary.HasKHRImageTexture2D() &&
|
||||||
|
gl->IsExtensionSupported(GLContext::OES_EGL_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedTextureHandle CreateSharedHandle(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
void* buffer,
|
||||||
|
SharedTextureBufferType bufferType)
|
||||||
|
{
|
||||||
|
// unimplemented outside of EGL
|
||||||
|
if (gl->GetContextType() != ContextTypeEGL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Both EGLImage and SurfaceTexture only support same-process currently, but
|
||||||
|
// it's possible to make SurfaceTexture work across processes. We should do that.
|
||||||
|
if (shareType != SameProcess)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (bufferType) {
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
case SharedTextureBufferType::SurfaceTexture:
|
||||||
|
if (!gl->IsExtensionSupported(GLContext::OES_EGL_image_external)) {
|
||||||
|
NS_WARNING("Missing GL_OES_EGL_image_external");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SharedTextureHandle) new SurfaceTextureWrapper(reinterpret_cast<nsSurfaceTexture*>(buffer));
|
||||||
|
#endif
|
||||||
|
case SharedTextureBufferType::TextureID: {
|
||||||
|
if (!DoesEGLContextSupportSharingWithEGLImage(gl))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
GLuint texture = (uintptr_t)buffer;
|
||||||
|
EGLTextureWrapper* tex = new EGLTextureWrapper();
|
||||||
|
if (!tex->CreateEGLImage(gl, texture)) {
|
||||||
|
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
||||||
|
delete tex;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SharedTextureHandle)tex;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NS_ERROR("Unknown shared texture buffer type");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReleaseSharedHandle(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
SharedTextureHandle sharedHandle)
|
||||||
|
{
|
||||||
|
// unimplemented outside of EGL
|
||||||
|
if (gl->GetContextType() != ContextTypeEGL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (shareType != SameProcess) {
|
||||||
|
NS_ERROR("Implementation not available for this sharing type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(sharedHandle);
|
||||||
|
|
||||||
|
switch (wrapper->Type()) {
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
case SharedHandleType_SurfaceTexture:
|
||||||
|
delete wrapper;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case SharedHandleType_Image: {
|
||||||
|
NS_ASSERTION(DoesEGLContextSupportSharingWithEGLImage(gl), "EGLImage not supported or disabled in runtime");
|
||||||
|
|
||||||
|
EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle;
|
||||||
|
delete wrap;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
NS_ERROR("Unknown shared handle type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetSharedHandleDetails(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
SharedTextureHandle sharedHandle,
|
||||||
|
SharedHandleDetails& details)
|
||||||
|
{
|
||||||
|
// unimplemented outside of EGL
|
||||||
|
if (gl->GetContextType() != ContextTypeEGL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (shareType != SameProcess)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(sharedHandle);
|
||||||
|
|
||||||
|
switch (wrapper->Type()) {
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
case SharedHandleType_SurfaceTexture: {
|
||||||
|
SurfaceTextureWrapper* surfaceWrapper = reinterpret_cast<SurfaceTextureWrapper*>(wrapper);
|
||||||
|
|
||||||
|
details.mTarget = LOCAL_GL_TEXTURE_EXTERNAL;
|
||||||
|
details.mTextureFormat = gfx::FORMAT_R8G8B8A8;
|
||||||
|
surfaceWrapper->SurfaceTexture()->GetTransformMatrix(details.mTextureTransform);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case SharedHandleType_Image:
|
||||||
|
details.mTarget = LOCAL_GL_TEXTURE_2D;
|
||||||
|
details.mTextureFormat = gfx::FORMAT_R8G8B8A8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NS_ERROR("Unknown shared handle type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AttachSharedHandle(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
SharedTextureHandle sharedHandle)
|
||||||
|
{
|
||||||
|
// unimplemented outside of EGL
|
||||||
|
if (gl->GetContextType() != ContextTypeEGL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (shareType != SameProcess)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(sharedHandle);
|
||||||
|
|
||||||
|
switch (wrapper->Type()) {
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
case SharedHandleType_SurfaceTexture: {
|
||||||
|
#ifndef DEBUG
|
||||||
|
/*
|
||||||
|
* NOTE: SurfaceTexture spams us if there are any existing GL errors, so we'll clear
|
||||||
|
* them here in order to avoid that.
|
||||||
|
*/
|
||||||
|
gl->GetAndClearError();
|
||||||
|
#endif
|
||||||
|
SurfaceTextureWrapper* surfaceTextureWrapper = reinterpret_cast<SurfaceTextureWrapper*>(wrapper);
|
||||||
|
|
||||||
|
// FIXME: SurfaceTexture provides a transform matrix which is supposed to
|
||||||
|
// be applied to the texture coordinates. We should return that here
|
||||||
|
// so we can render correctly. Bug 775083
|
||||||
|
surfaceTextureWrapper->SurfaceTexture()->UpdateTexImage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif // MOZ_WIDGET_ANDROID
|
||||||
|
|
||||||
|
case SharedHandleType_Image: {
|
||||||
|
NS_ASSERTION(DoesEGLContextSupportSharingWithEGLImage(gl), "EGLImage not supported or disabled in runtime");
|
||||||
|
|
||||||
|
EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle;
|
||||||
|
wrap->WaitSync();
|
||||||
|
gl->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
NS_ERROR("Unknown shared handle type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach Shared GL Handle from GL_TEXTURE_2D target
|
||||||
|
*/
|
||||||
|
void DetachSharedHandle(GLContext*,
|
||||||
|
SharedTextureShareType,
|
||||||
|
SharedTextureHandle)
|
||||||
|
{
|
||||||
|
// currently a no-operation
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
73
gfx/gl/GLSharedHandleHelpers.h
Normal file
73
gfx/gl/GLSharedHandleHelpers.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#ifndef GLSHAREDHANDLEHELPERS_H_
|
||||||
|
#define GLSHAREDHANDLEHELPERS_H_
|
||||||
|
|
||||||
|
#include "GLContextTypes.h"
|
||||||
|
#include "mozilla/gfx/Types.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new shared GLContext content handle, using the passed buffer as a source.
|
||||||
|
* Must be released by ReleaseSharedHandle.
|
||||||
|
*/
|
||||||
|
SharedTextureHandle CreateSharedHandle(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
void* buffer,
|
||||||
|
SharedTextureBufferType bufferType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - It is better to call ReleaseSharedHandle before original GLContext destroyed,
|
||||||
|
* otherwise warning will be thrown on attempt to destroy Texture associated with SharedHandle, depends on backend implementation.
|
||||||
|
* - It does not require to be called on context where it was created,
|
||||||
|
* because SharedHandle suppose to keep Context reference internally,
|
||||||
|
* or don't require specific context at all, for example IPC SharedHandle.
|
||||||
|
* - Not recommended to call this between AttachSharedHandle and Draw Target call.
|
||||||
|
* if it is really required for some special backend, then DetachSharedHandle API must be added with related implementation.
|
||||||
|
* - It is recommended to stop any possible access to SharedHandle (Attachments, pending GL calls) before calling Release,
|
||||||
|
* otherwise some artifacts might appear or even crash if API backend implementation does not expect that.
|
||||||
|
* SharedHandle (currently EGLImage) does not require GLContext because it is EGL call, and can be destroyed
|
||||||
|
* at any time, unless EGLImage have siblings (which are not expected with current API).
|
||||||
|
*/
|
||||||
|
void ReleaseSharedHandle(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
SharedTextureHandle sharedHandle);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GLenum mTarget;
|
||||||
|
gfx::SurfaceFormat mTextureFormat;
|
||||||
|
gfx3DMatrix mTextureTransform;
|
||||||
|
} SharedHandleDetails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information necessary for rendering a shared handle.
|
||||||
|
* These values change depending on what sharing mechanism is in use
|
||||||
|
*/
|
||||||
|
bool GetSharedHandleDetails(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
SharedTextureHandle sharedHandle,
|
||||||
|
SharedHandleDetails& details);
|
||||||
|
/**
|
||||||
|
* Attach Shared GL Handle to GL_TEXTURE_2D target
|
||||||
|
* GLContext must be current before this call
|
||||||
|
*/
|
||||||
|
bool AttachSharedHandle(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
SharedTextureHandle sharedHandle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach Shared GL Handle from GL_TEXTURE_2D target
|
||||||
|
*/
|
||||||
|
void DetachSharedHandle(GLContext* gl,
|
||||||
|
SharedTextureShareType shareType,
|
||||||
|
SharedTextureHandle sharedHandle);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -41,6 +41,7 @@ EXPORTS += [
|
|||||||
'GLLibraryEGL.h',
|
'GLLibraryEGL.h',
|
||||||
'GLLibraryLoader.h',
|
'GLLibraryLoader.h',
|
||||||
'GLScreenBuffer.h',
|
'GLScreenBuffer.h',
|
||||||
|
'GLSharedHandleHelpers.h',
|
||||||
'GLTextureImage.h',
|
'GLTextureImage.h',
|
||||||
'GLTypes.h',
|
'GLTypes.h',
|
||||||
'ScopedGLHelpers.h',
|
'ScopedGLHelpers.h',
|
||||||
@ -117,6 +118,7 @@ UNIFIED_SOURCES += [
|
|||||||
'GLLibraryEGL.cpp',
|
'GLLibraryEGL.cpp',
|
||||||
'GLLibraryLoader.cpp',
|
'GLLibraryLoader.cpp',
|
||||||
'GLScreenBuffer.cpp',
|
'GLScreenBuffer.cpp',
|
||||||
|
'GLSharedHandleHelpers.cpp',
|
||||||
'GLTextureImage.cpp',
|
'GLTextureImage.cpp',
|
||||||
'ScopedGLHelpers.cpp',
|
'ScopedGLHelpers.cpp',
|
||||||
'SharedSurface.cpp',
|
'SharedSurface.cpp',
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "TextureHostOGL.h"
|
#include "TextureHostOGL.h"
|
||||||
#include "GLContext.h" // for GLContext, etc
|
#include "GLContext.h" // for GLContext, etc
|
||||||
|
#include "GLSharedHandleHelpers.h"
|
||||||
#include "GLContextUtils.h" // for GLContextUtils
|
#include "GLContextUtils.h" // for GLContextUtils
|
||||||
#include "SharedSurface.h" // for SharedSurface
|
#include "SharedSurface.h" // for SharedSurface
|
||||||
#include "SharedSurfaceEGL.h" // for SharedSurface_EGLImage
|
#include "SharedSurfaceEGL.h" // for SharedSurface_EGLImage
|
||||||
@ -325,7 +326,7 @@ SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit)
|
|||||||
|
|
||||||
gl()->fActiveTexture(aTextureUnit);
|
gl()->fActiveTexture(aTextureUnit);
|
||||||
gl()->fBindTexture(mTextureTarget, tex);
|
gl()->fBindTexture(mTextureTarget, tex);
|
||||||
if (!gl()->AttachSharedHandle(mShareType, mSharedHandle)) {
|
if (!AttachSharedHandle(gl(), mShareType, mSharedHandle)) {
|
||||||
NS_ERROR("Failed to bind shared texture handle");
|
NS_ERROR("Failed to bind shared texture handle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -338,7 +339,7 @@ SharedTextureSourceOGL::DetachSharedHandle()
|
|||||||
if (!gl()) {
|
if (!gl()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gl()->DetachSharedHandle(mShareType, mSharedHandle);
|
gl::DetachSharedHandle(gl(), mShareType, mSharedHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -362,8 +363,8 @@ SharedTextureSourceOGL::gl() const
|
|||||||
gfx3DMatrix
|
gfx3DMatrix
|
||||||
SharedTextureSourceOGL::GetTextureTransform()
|
SharedTextureSourceOGL::GetTextureTransform()
|
||||||
{
|
{
|
||||||
GLContext::SharedHandleDetails handleDetails;
|
SharedHandleDetails handleDetails;
|
||||||
if (!gl()->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
|
if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) {
|
||||||
NS_WARNING("Could not get shared handle details");
|
NS_WARNING("Could not get shared handle details");
|
||||||
return gfx3DMatrix();
|
return gfx3DMatrix();
|
||||||
}
|
}
|
||||||
@ -407,8 +408,8 @@ SharedTextureHostOGL::Lock()
|
|||||||
if (!mTextureSource) {
|
if (!mTextureSource) {
|
||||||
// XXX on android GetSharedHandleDetails can call into Java which we'd
|
// XXX on android GetSharedHandleDetails can call into Java which we'd
|
||||||
// rather not do from the compositor
|
// rather not do from the compositor
|
||||||
GLContext::SharedHandleDetails handleDetails;
|
SharedHandleDetails handleDetails;
|
||||||
if (!gl()->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
|
if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) {
|
||||||
NS_WARNING("Could not get shared handle details");
|
NS_WARNING("Could not get shared handle details");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -616,7 +617,7 @@ SharedDeprecatedTextureHostOGL::DeleteTextures()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mSharedHandle) {
|
if (mSharedHandle) {
|
||||||
mGL->ReleaseSharedHandle(mShareType, mSharedHandle);
|
ReleaseSharedHandle(mGL, mShareType, mSharedHandle);
|
||||||
mSharedHandle = 0;
|
mSharedHandle = 0;
|
||||||
}
|
}
|
||||||
if (mTextureHandle) {
|
if (mTextureHandle) {
|
||||||
@ -650,14 +651,14 @@ SharedDeprecatedTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mSharedHandle && mSharedHandle != newHandle) {
|
if (mSharedHandle && mSharedHandle != newHandle) {
|
||||||
mGL->ReleaseSharedHandle(mShareType, mSharedHandle);
|
ReleaseSharedHandle(mGL, mShareType, mSharedHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
mShareType = texture.shareType();
|
mShareType = texture.shareType();
|
||||||
mSharedHandle = newHandle;
|
mSharedHandle = newHandle;
|
||||||
|
|
||||||
GLContext::SharedHandleDetails handleDetails;
|
SharedHandleDetails handleDetails;
|
||||||
if (mSharedHandle && mGL->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
|
if (mSharedHandle && GetSharedHandleDetails(mGL, mShareType, mSharedHandle, handleDetails)) {
|
||||||
mTextureTarget = handleDetails.mTarget;
|
mTextureTarget = handleDetails.mTarget;
|
||||||
mFormat = handleDetails.mTextureFormat;
|
mFormat = handleDetails.mTextureFormat;
|
||||||
}
|
}
|
||||||
@ -670,7 +671,7 @@ SharedDeprecatedTextureHostOGL::Lock()
|
|||||||
|
|
||||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
|
mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||||
mGL->fBindTexture(mTextureTarget, mTextureHandle);
|
mGL->fBindTexture(mTextureTarget, mTextureHandle);
|
||||||
if (!mGL->AttachSharedHandle(mShareType, mSharedHandle)) {
|
if (!AttachSharedHandle(mGL, mShareType, mSharedHandle)) {
|
||||||
NS_ERROR("Failed to bind shared texture handle");
|
NS_ERROR("Failed to bind shared texture handle");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -681,7 +682,7 @@ SharedDeprecatedTextureHostOGL::Lock()
|
|||||||
void
|
void
|
||||||
SharedDeprecatedTextureHostOGL::Unlock()
|
SharedDeprecatedTextureHostOGL::Unlock()
|
||||||
{
|
{
|
||||||
mGL->DetachSharedHandle(mShareType, mSharedHandle);
|
DetachSharedHandle(mGL, mShareType, mSharedHandle);
|
||||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
|
mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,11 +690,11 @@ SharedDeprecatedTextureHostOGL::Unlock()
|
|||||||
gfx3DMatrix
|
gfx3DMatrix
|
||||||
SharedDeprecatedTextureHostOGL::GetTextureTransform()
|
SharedDeprecatedTextureHostOGL::GetTextureTransform()
|
||||||
{
|
{
|
||||||
GLContext::SharedHandleDetails handleDetails;
|
SharedHandleDetails handleDetails;
|
||||||
// GetSharedHandleDetails can call into Java which we'd
|
// GetSharedHandleDetails can call into Java which we'd
|
||||||
// rather not do from the compositor
|
// rather not do from the compositor
|
||||||
if (mSharedHandle) {
|
if (mSharedHandle) {
|
||||||
mGL->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails);
|
GetSharedHandleDetails(mGL, mShareType, mSharedHandle, handleDetails);
|
||||||
}
|
}
|
||||||
return handleDetails.mTextureTransform;
|
return handleDetails.mTextureTransform;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user