Commit 6dc4d165 authored by James Willcox's avatar James Willcox
Browse files

Bug 956993 - Rely on OES_EGL_image_external for SharedSurface_EGLImage r=jgilbert

parent 079e0583
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ ScopedBindTexture::Init(GLenum aTarget)
    GLenum bindingTarget = (aTarget == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_BINDING_2D
                         : (aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) ? LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB
                         : (aTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? LOCAL_GL_TEXTURE_BINDING_CUBE_MAP
                         : (aTarget == LOCAL_GL_TEXTURE_EXTERNAL) ? LOCAL_GL_TEXTURE_EXTERNAL
                         : LOCAL_GL_NONE;
    MOZ_ASSERT(bindingTarget != LOCAL_GL_NONE);
    mGL->GetUIntegerv(bindingTarget, &mOldTex);
+27 −119
Original line number Diff line number Diff line
@@ -27,18 +27,30 @@ SharedSurface_EGLImage::Create(GLContext* prodGL,
{
    GLLibraryEGL* egl = &sEGLLibrary;
    MOZ_ASSERT(egl);
    MOZ_ASSERT(context);

    if (!HasExtensions(egl, prodGL))
    if (!HasExtensions(egl, prodGL)) {
        return nullptr;
    }

    MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
    GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size);
    if (!prodTex)
    if (!prodTex) {
        return nullptr;
    }

    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(prodTex);
    EGLImage image = egl->fCreateImage(egl->Display(), context,
                                       LOCAL_EGL_GL_TEXTURE_2D, buffer,
                                       nullptr);
    if (!image) {
        prodGL->fDeleteTextures(1, &prodTex);
        return nullptr;
    }

    return new SharedSurface_EGLImage(prodGL, egl,
                                      size, hasAlpha,
                                      formats, prodTex);
                                      formats, prodTex, image);
}


@@ -47,7 +59,7 @@ SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
{
    return egl->HasKHRImageBase() &&
           egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) &&
           gl->IsExtensionSupported(GLContext::OES_EGL_image);
           gl->IsExtensionSupported(GLContext::OES_EGL_image_external);
}

SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
@@ -55,7 +67,8 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
                                               const gfx::IntSize& size,
                                               bool hasAlpha,
                                               const GLFormats& formats,
                                               GLuint prodTex)
                                               GLuint prodTex,
                                               EGLImage image)
    : SharedSurface_GL(SharedSurfaceType::EGLImageShare,
                        AttachmentType::GLTexture,
                        gl,
@@ -65,14 +78,10 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
    , mEGL(egl)
    , mFormats(formats)
    , mProdTex(prodTex)
    , mProdTexForPipe(0)
    , mImage(0)
    , mImage(image)
    , mCurConsGL(nullptr)
    , mConsTex(0)
    , mSync(0)
    , mPipeFailed(false)
    , mPipeComplete(false)
    , mPipeActive(false)
{}

SharedSurface_EGLImage::~SharedSurface_EGLImage()
@@ -84,11 +93,6 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage()
    mGL->fDeleteTextures(1, &mProdTex);
    mProdTex = 0;

    if (mProdTexForPipe) {
        mGL->fDeleteTextures(1, &mProdTexForPipe);
        mProdTexForPipe = 0;
    }

    if (mConsTex) {
        MOZ_ASSERT(mGarbageBin);
        mGarbageBin->Trash(mConsTex);
@@ -103,94 +107,12 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage()
    }
}

void
SharedSurface_EGLImage::LockProdImpl()
{
    MutexAutoLock lock(mMutex);

    if (!mPipeComplete)
        return;

    if (mPipeActive)
        return;

    mGL->BlitHelper()->BlitTextureToTexture(mProdTex, mProdTexForPipe, Size(), Size());
    mGL->fDeleteTextures(1, &mProdTex);
    mProdTex = mProdTexForPipe;
    mProdTexForPipe = 0;
    mPipeActive = true;
}

static bool
CreateTexturePipe(GLLibraryEGL* const egl, GLContext* const gl,
                  const GLFormats& formats, const gfx::IntSize& size,
                  GLuint* const out_tex, EGLImage* const out_image)
{
    MOZ_ASSERT(out_tex && out_image);
    *out_tex = 0;
    *out_image = 0;

    GLuint tex = CreateTextureForOffscreen(gl, formats, size);
    if (!tex)
        return false;

    EGLContext context = GLContextEGL::Cast(gl)->GetEGLContext();
    MOZ_ASSERT(context);
    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex);
    EGLImage image = egl->fCreateImage(egl->Display(), context,
                                       LOCAL_EGL_GL_TEXTURE_2D, buffer,
                                       nullptr);
    if (!image) {
        gl->fDeleteTextures(1, &tex);
        return false;
    }

    // Success.
    *out_tex = tex;
    *out_image = image;
    return true;
}

void
SharedSurface_EGLImage::Fence()
{
    MutexAutoLock lock(mMutex);
    mGL->MakeCurrent();

    if (!mPipeActive) {
        MOZ_ASSERT(!mSync);
        MOZ_ASSERT(!mPipeComplete);

        if (!mPipeFailed) {
            if (!CreateTexturePipe(mEGL, mGL, mFormats, Size(),
                                   &mProdTexForPipe, &mImage))
            {
                mPipeFailed = true;
            }
        }

        if (!mPixels) {
            SurfaceFormat format =
                  HasAlpha() ? SurfaceFormat::B8G8R8A8
                             : SurfaceFormat::B8G8R8X8;
            mPixels = Factory::CreateDataSourceSurface(Size(), format);
        }

        DataSourceSurface::MappedSurface map;
        mPixels->Map(DataSourceSurface::MapType::WRITE, &map);

        nsRefPtr<gfxImageSurface> wrappedData =
            new gfxImageSurface(map.mData,
                                ThebesIntSize(mPixels->GetSize()),
                                map.mStride,
                                SurfaceFormatToImageFormat(mPixels->GetFormat()));
        ReadScreenIntoImageSurface(mGL, wrappedData);
        mPixels->Unmap();
        return;
    }
    MOZ_ASSERT(mPipeActive);
    MOZ_ASSERT(mCurConsGL);

    if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
        mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
    {
@@ -249,42 +171,28 @@ SharedSurface_EGLImage::Display() const
    return mEGL->Display();
}

GLuint
SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL)
void
SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target)
{
    MutexAutoLock lock(mMutex);
    MOZ_ASSERT(!mCurConsGL || consGL == mCurConsGL);
    if (mPipeFailed)
        return 0;

    if (mPipeActive) {
        MOZ_ASSERT(mConsTex);

        return mConsTex;
    }

    if (!mConsTex) {
        consGL->fGenTextures(1, &mConsTex);
        ScopedBindTexture autoTex(consGL, mConsTex);
        consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage);
        MOZ_ASSERT(mConsTex);

        ScopedBindTexture autoTex(consGL, mConsTex, LOCAL_GL_TEXTURE_EXTERNAL);
        consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mImage);

        mPipeComplete = true;
        mCurConsGL = consGL;
        mGarbageBin = consGL->TexGarbageBin();
    }

    MOZ_ASSERT(consGL == mCurConsGL);
    return 0;
    *out_texture = mConsTex;
    *out_target = LOCAL_GL_TEXTURE_EXTERNAL;
}

DataSourceSurface*
SharedSurface_EGLImage::GetPixels() const
{
    MutexAutoLock lock(mMutex);
    return mPixels;
}



SurfaceFactory_EGLImage*
SurfaceFactory_EGLImage::Create(GLContext* prodGL,
+5 −12
Original line number Diff line number Diff line
@@ -40,23 +40,19 @@ protected:
    GLLibraryEGL* const mEGL;
    const GLFormats mFormats;
    GLuint mProdTex;
    RefPtr<gfx::DataSourceSurface> mPixels;
    GLuint mProdTexForPipe; // Moves to mProdTex when mPipeActive becomes true.
    EGLImage mImage;
    GLContext* mCurConsGL;
    GLuint mConsTex;
    nsRefPtr<TextureGarbageBin> mGarbageBin;
    EGLSync mSync;
    bool mPipeFailed;   // Pipe creation failed, and has been abandoned.
    bool mPipeComplete; // Pipe connects (mPipeActive ? mProdTex : mProdTexForPipe) to mConsTex.
    bool mPipeActive;   // Pipe is complete and in use for production.

    SharedSurface_EGLImage(GLContext* gl,
                           GLLibraryEGL* egl,
                           const gfx::IntSize& size,
                           bool hasAlpha,
                           const GLFormats& formats,
                           GLuint prodTex);
                           GLuint prodTex,
                           EGLImage image);

    EGLDisplay Display() const;

@@ -65,7 +61,7 @@ protected:
public:
    virtual ~SharedSurface_EGLImage();

    virtual void LockProdImpl();
    virtual void LockProdImpl() {}
    virtual void UnlockProdImpl() {}


@@ -78,11 +74,8 @@ public:
    }

    // Implementation-specific functions below:
    // Returns 0 if the pipe isn't ready. If 0, use GetPixels below.
    GLuint AcquireConsumerTexture(GLContext* consGL);

    // Will be void if AcquireConsumerTexture returns non-zero.
    gfx::DataSourceSurface* GetPixels() const;
    // Returns texture and target
    void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target);
};


+4 −9
Original line number Diff line number Diff line
@@ -515,15 +515,10 @@ StreamTextureSourceOGL::RetrieveTextureFromStream()
      SharedSurface_EGLImage* eglImageSurf =
          SharedSurface_EGLImage::Cast(sharedSurf);

      mTextureHandle = eglImageSurf->AcquireConsumerTexture(gl());
      mTextureTarget = eglImageSurf->TextureTarget();
      if (!mTextureHandle) {
        toUpload = eglImageSurf->GetPixels();
        MOZ_ASSERT(toUpload);
      } else {
      eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget);
      MOZ_ASSERT(mTextureHandle);
      mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
                                       : SurfaceFormat::R8G8B8X8;
      }
      break;
    }
#ifdef XP_MACOSX