Exemplo n.º 1
0
bool
EGLImageTextureHost::Lock()
{
  if (!mCompositor) {
    return false;
  }

  EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
  if (status != LOCAL_EGL_CONDITION_SATISFIED) {
    return false;
  }

  if (!mTextureSource) {
    gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
    GLenum target = LOCAL_GL_TEXTURE_2D;
    GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
    mTextureSource = new EGLImageTextureSource(mCompositor,
                                               mImage,
                                               format,
                                               target,
                                               wrapMode,
                                               mSize);
  }

  return true;
}
Exemplo n.º 2
0
bool
EGLImageTextureHost::Lock()
{
  if (!mCompositor) {
    return false;
  }

  EGLint status = LOCAL_EGL_CONDITION_SATISFIED;

  if (mSync) {
    MOZ_ASSERT(sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
    status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
  }

  if (status != LOCAL_EGL_CONDITION_SATISFIED) {
    MOZ_ASSERT(status != 0,
               "ClientWaitSync generated an error. Has mSync already been destroyed?");
    return false;
  }

  if (!mTextureSource) {
    gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
                                          : gfx::SurfaceFormat::R8G8B8X8;
    GLenum target = LOCAL_GL_TEXTURE_EXTERNAL;
    GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
    mTextureSource = new EGLImageTextureSource(mCompositor,
                                               mImage,
                                               format,
                                               target,
                                               wrapMode,
                                               mSize);
  }

  return true;
}
Exemplo n.º 3
0
EGLImageImage::~EGLImageImage()
{
  if (!mOwns) {
    return;
  }

  if (mImage) {
    sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mImage);
    mImage = nullptr;
  }

  if (mSync) {
    sEGLLibrary.fDestroySync(EGL_DISPLAY(), mSync);
    mSync = nullptr;
  }
}
Exemplo n.º 4
0
  EGLImage CopySurface(layers::Image* img) {
    mGLContext->MakeCurrent();

    GLuint tex = CreateTextureForOffscreen(mGLContext, mGLContext->GetGLFormats(),
                                           img->GetSize());

    auto helper = mGLContext->BlitHelper();
    const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
    if (!helper->BlitImageToTexture(img, img->GetSize(), tex, LOCAL_GL_TEXTURE_2D,
                                    destOrigin))
    {
      mGLContext->fDeleteTextures(1, &tex);
      return nullptr;
    }

    EGLint attribs[] = {
      LOCAL_EGL_IMAGE_PRESERVED_KHR, LOCAL_EGL_TRUE,
      LOCAL_EGL_NONE, LOCAL_EGL_NONE
    };

    EGLContext eglContext = static_cast<GLContextEGL*>(mGLContext.get())->GetEGLContext();
    EGLImage eglImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext,
                                                 LOCAL_EGL_GL_TEXTURE_2D_KHR,
                                                 (EGLClientBuffer)tex, attribs);
    mGLContext->fDeleteTextures(1, &tex);

    return eglImage;
  }
Exemplo n.º 5
0
void
TextureImageEGL::DestroyEGLSurface(void)
{
    if (!mSurface)
        return;

    sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
    mSurface = nullptr;
}
Exemplo n.º 6
0
void
TextureHostOGL::WaitAcquireFenceSyncComplete()
{
  if (!mAcquireFence.get() || !mAcquireFence->isValid()) {
    return;
  }

  int fenceFd = mAcquireFence->dup();
  if (fenceFd == -1) {
    NS_WARNING("failed to dup fence fd");
    return;
  }

  EGLint attribs[] = {
              LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd,
              LOCAL_EGL_NONE
          };

  EGLSync sync = sEGLLibrary.fCreateSync(EGL_DISPLAY(),
                                         LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID,
                                         attribs);
  if (!sync) {
    NS_WARNING("failed to create native fence sync");
    return;
  }

  // Wait sync complete with timeout.
  // If a source of the fence becomes invalid because of error,
  // fene complete is not signaled. See Bug 1061435.
  EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(),
                                              sync,
                                              0,
                                              400000000 /*400 usec*/);
  if (status != LOCAL_EGL_CONDITION_SATISFIED) {
    NS_ERROR("failed to wait native fence sync");
  }
  MOZ_ALWAYS_TRUE( sEGLLibrary.fDestroySync(EGL_DISPLAY(), sync) );
  mAcquireFence = nullptr;
}
Exemplo n.º 7
0
EGLImage
CreateEGLImage(GLContext* gl, GLuint tex)
{
    MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));

    EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
    EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
    EGLImage image = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
                                              eglContext,
                                              LOCAL_EGL_GL_TEXTURE_2D,
                                              clientBuffer,
                                              nullptr);
    return image;
}
Exemplo n.º 8
0
void
TextureHostOGL::WaitAcquireFenceSyncComplete()
{
  if (!mAcquireFence.get() || !mAcquireFence->isValid()) {
    return;
  }

  int fenceFd = mAcquireFence->dup();
  if (fenceFd == -1) {
    NS_WARNING("failed to dup fence fd");
    return;
  }

  EGLint attribs[] = {
              LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd,
              LOCAL_EGL_NONE
          };

  EGLSync sync = sEGLLibrary.fCreateSync(EGL_DISPLAY(),
                                         LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID,
                                         attribs);
  if (!sync) {
    NS_WARNING("failed to create native fence sync");
    return;
  }

  EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(),
                                              sync,
                                              0,
                                              LOCAL_EGL_FOREVER);
  if (status != LOCAL_EGL_CONDITION_SATISFIED) {
    NS_WARNING("failed to wait native fence sync");
  }
  MOZ_ALWAYS_TRUE( sEGLLibrary.fDestroySync(EGL_DISPLAY(), sync) );
  mAcquireFence = nullptr;
}
Exemplo n.º 9
0
bool
TextureImageEGL::ReleaseTexImage()
{
    if (!mBound)
        return true;

    EGLBoolean success =
        sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
                                      (EGLSurface)mSurface,
                                      LOCAL_EGL_BACK_BUFFER);

    if (success == LOCAL_EGL_FALSE)
        return false;

    mBound = false;
    return true;
}
Exemplo n.º 10
0
/*static*/ EGLImageWrapper*
EGLImageWrapper::Create(GLContext* gl, GLuint tex)
{
    MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));

    GLLibraryEGL& library = sEGLLibrary;
    EGLDisplay display = EGL_DISPLAY();
    EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
    EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
    EGLImage image = library.fCreateImage(display,
                                          eglContext,
                                          LOCAL_EGL_GL_TEXTURE_2D,
                                          clientBuffer,
                                          nullptr);
    if (!image) {
#ifdef DEBUG
        printf_stderr("Could not create EGL images: ERROR (0x%04x)\n",
                      sEGLLibrary.fGetError());
#endif
        return nullptr;
    }

    return new EGLImageWrapper(library, display, image);
}
Exemplo n.º 11
0
bool
EGLImageTextureHost::Lock()
{
  GLContext* gl = this->gl();
  if (!gl || !gl->MakeCurrent()) {
    return false;
  }

  EGLint status = LOCAL_EGL_CONDITION_SATISFIED;

  if (mSync) {
    MOZ_ASSERT(sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
    status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
  }

  if (status != LOCAL_EGL_CONDITION_SATISFIED) {
    MOZ_ASSERT(status != 0,
               "ClientWaitSync generated an error. Has mSync already been destroyed?");
    return false;
  }

  if (!mTextureSource) {
    gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
                                          : gfx::SurfaceFormat::R8G8B8X8;
    GLenum target = gl->GetPreferredEGLImageTextureTarget();
    GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
    mTextureSource = new EGLImageTextureSource(mProvider,
                                               mImage,
                                               format,
                                               target,
                                               wrapMode,
                                               mSize);
  }

  return true;
}
Exemplo n.º 12
0
  virtual nsresult PostOutput(BufferInfo::Param aInfo, MediaFormat::Param aFormat,
                              const media::TimeUnit& aDuration) override {
    if (!EnsureGLContext()) {
      return NS_ERROR_FAILURE;
    }

    nsRefPtr<layers::Image> img = mImageContainer->CreateImage(ImageFormat::SURFACE_TEXTURE);
    layers::SurfaceTextureImage::Data data;
    data.mSurfTex = mSurfaceTexture.get();
    data.mSize = mConfig.mDisplay;
    data.mOriginPos = gl::OriginPos::BottomLeft;

    layers::SurfaceTextureImage* stImg = static_cast<layers::SurfaceTextureImage*>(img.get());
    stImg->SetData(data);

    if (WantCopy()) {
      EGLImage eglImage = CopySurface(img);
      if (!eglImage) {
        return NS_ERROR_FAILURE;
      }

      EGLSync eglSync = nullptr;
      if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
          mGLContext->IsExtensionSupported(GLContext::OES_EGL_sync))
      {
        MOZ_ASSERT(mGLContext->IsCurrent());
        eglSync = sEGLLibrary.fCreateSync(EGL_DISPLAY(),
                                          LOCAL_EGL_SYNC_FENCE,
                                          nullptr);
        MOZ_ASSERT(eglSync);
        mGLContext->fFlush();
      } else {
        NS_WARNING("No EGL fence support detected, rendering artifacts may occur!");
      }

      img = mImageContainer->CreateImage(ImageFormat::EGLIMAGE);
      layers::EGLImageImage::Data data;
      data.mImage = eglImage;
      data.mSync = eglSync;
      data.mOwns = true;
      data.mSize = mConfig.mDisplay;
      data.mOriginPos = gl::OriginPos::TopLeft;

      layers::EGLImageImage* typedImg = static_cast<layers::EGLImageImage*>(img.get());
      typedImg->SetData(data);
    }

    nsresult rv;
    int32_t flags;
    NS_ENSURE_SUCCESS(rv = aInfo->Flags(&flags), rv);

    bool isSync = !!(flags & MediaCodec::BUFFER_FLAG_SYNC_FRAME);

    int32_t offset;
    NS_ENSURE_SUCCESS(rv = aInfo->Offset(&offset), rv);

    int64_t presentationTimeUs;
    NS_ENSURE_SUCCESS(rv = aInfo->PresentationTimeUs(&presentationTimeUs), rv);

    nsRefPtr<VideoData> v =
      VideoData::CreateFromImage(mConfig,
                                 mImageContainer,
                                 offset,
                                 presentationTimeUs,
                                 aDuration.ToMicroseconds(),
                                 img,
                                 isSync,
                                 presentationTimeUs,
                                 gfx::IntRect(0, 0,
                                              mConfig.mDisplay.width,
                                              mConfig.mDisplay.height));
    ENVOKE_CALLBACK(Output, v);
    return NS_OK;
  }