bool
SurfaceStreamHostOGL::Lock()
{
  mGL->MakeCurrent();

  SharedSurface* sharedSurf = mStream->SwapConsumer();
  if (!sharedSurf) {
    // We don't have a valid surf to show yet.
    return false;
  }

  mGL->MakeCurrent();

  mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height);

  gfxImageSurface* toUpload = nullptr;
  switch (sharedSurf->Type()) {
    case SharedSurfaceType::GLTextureShare: {
      SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf);
      glTexSurf->SetConsumerGL(mGL);
      mTextureHandle = glTexSurf->Texture();
      mTextureTarget = glTexSurf->TextureTarget();
      MOZ_ASSERT(mTextureHandle);
      mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8
                                       : FORMAT_R8G8B8X8;
      break;
    }
    case SharedSurfaceType::EGLImageShare: {
      SharedSurface_EGLImage* eglImageSurf =
          SharedSurface_EGLImage::Cast(sharedSurf);

      mTextureHandle = eglImageSurf->AcquireConsumerTexture(mGL);
      mTextureTarget = eglImageSurf->TextureTarget();
      if (!mTextureHandle) {
        toUpload = eglImageSurf->GetPixels();
        MOZ_ASSERT(toUpload);
      } else {
        mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8
                                         : FORMAT_R8G8B8X8;
      }
      break;
    }
#ifdef XP_MACOSX
    case SharedSurfaceType::IOSurface: {
      SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf);
      mTextureHandle = glTexSurf->Texture();
      mTextureTarget = glTexSurf->TextureTarget();
      MOZ_ASSERT(mTextureHandle);
      mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8
                                       : FORMAT_R8G8B8X8;
      break;
    }
#endif
    case SharedSurfaceType::Basic: {
      toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData();
      MOZ_ASSERT(toUpload);
      break;
    }
    default:
      MOZ_CRASH("Invalid SharedSurface type.");
  }

  if (toUpload) {
    // mBounds seems to end up as (0,0,0,0) a lot, so don't use it?
    nsIntSize size(toUpload->GetSize());
    nsIntRect rect(nsIntPoint(0,0), size);
    nsIntRegion bounds(rect);
    mFormat = mGL->UploadSurfaceToTexture(toUpload,
                                          bounds,
                                          mUploadTexture,
                                          true);
    mTextureHandle = mUploadTexture;
    mTextureTarget = LOCAL_GL_TEXTURE_2D;
  }

  MOZ_ASSERT(mTextureHandle);
  mGL->fBindTexture(mTextureTarget, mTextureHandle);
  mGL->fTexParameteri(mTextureTarget,
                      LOCAL_GL_TEXTURE_WRAP_S,
                      LOCAL_GL_CLAMP_TO_EDGE);
  mGL->fTexParameteri(mTextureTarget,
                      LOCAL_GL_TEXTURE_WRAP_T,
                      LOCAL_GL_CLAMP_TO_EDGE);
  return true;
}
/**
 * Following UpdateSurface(), mTexture on context this->gl() should contain the data we want,
 * unless mDelayedUpdates is true because of a too-large surface.
 */
void
CanvasLayerOGL::UpdateSurface()
{
  if (!IsDirty())
    return;
  Painted();

  if (mDestroyed || mDelayedUpdates) {
    return;
  }

#if defined(GL_PROVIDER_GLX)
  if (mPixmap) {
    return;
  }
#endif

  gfxASurface* updatedSurface = nullptr;
  gfxImageSurface* temporarySurface = nullptr;
  bool nothingToShow = false;
  if (mGLContext) {
    SharedSurface* surf = mGLContext->RequestFrame();
    if (surf) {
      mLayerProgram = surf->HasAlpha() ? RGBALayerProgramType
                                       : RGBXLayerProgramType;
      switch (surf->Type()) {
        case SharedSurfaceType::Basic: {
          SharedSurface_Basic* readbackSurf = SharedSurface_Basic::Cast(surf);
          updatedSurface = readbackSurf->GetData();
          break;
        }
        case SharedSurfaceType::GLTextureShare: {
          SharedSurface_GLTexture* textureSurf = SharedSurface_GLTexture::Cast(surf);
          mTexture = textureSurf->Texture();
          break;
        }
#ifdef XP_MACOSX
        case SharedSurfaceType::IOSurface: {
          SharedSurface_IOSurface *ioSurf = SharedSurface_IOSurface::Cast(surf);
          mTexture = ioSurf->Texture();
          mTextureTarget = ioSurf->TextureTarget();
          mLayerProgram = ioSurf->HasAlpha() ? RGBARectLayerProgramType : RGBXRectLayerProgramType;
          break;
        }
#endif
        default:
          MOZ_CRASH("Unacceptable SharedSurface type.");
      }
    } else {
      nothingToShow = true;
    }
  } else if (mCanvasSurface) {
#ifdef XP_MACOSX
    if (mDrawTarget && mDrawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT_ACCELERATED)) {
      if (!mTexture) {
        mTexture = MakeIOSurfaceTexture((CGContextRef)mDrawTarget->GetNativeSurface(
                                        gfx::NATIVE_SURFACE_CGCONTEXT_ACCELERATED),
                                        gl());
        mTextureTarget = LOCAL_GL_TEXTURE_RECTANGLE_ARB;
        mLayerProgram = RGBARectLayerProgramType;
      }
      mDrawTarget->Flush();
      return;
    }
#endif
    updatedSurface = mCanvasSurface;
  } else {
    MOZ_CRASH("Unhandled canvas layer type.");
  }

  if (updatedSurface) {
    mOGLManager->MakeCurrent();
    gfx::SurfaceFormat format =
      gl()->UploadSurfaceToTexture(updatedSurface,
                                   mBounds,
                                   mUploadTexture,
                                   true,//false,
                                   nsIntPoint(0, 0));
    mLayerProgram = ShaderProgramFromSurfaceFormat(format);
    mTexture = mUploadTexture;

    if (temporarySurface)
      delete temporarySurface;
  }

  MOZ_ASSERT(mTexture || nothingToShow);
}
Exemple #3
0
bool
StreamTextureSourceOGL::RetrieveTextureFromStream()
{
    gl()->MakeCurrent();

    SharedSurface* sharedSurf = mStream->SwapConsumer();
    if (!sharedSurf) {
        // We don't have a valid surf to show yet.
        return false;
    }

    gl()->MakeCurrent();

    mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height);

    DataSourceSurface* toUpload = nullptr;
    switch (sharedSurf->Type()) {
    case SharedSurfaceType::GLTextureShare: {
        SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf);
        mTextureHandle = glTexSurf->ConsTexture(gl());
        mTextureTarget = glTexSurf->ConsTextureTarget();
        MOZ_ASSERT(mTextureHandle);
        mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
                  : SurfaceFormat::R8G8B8X8;
        break;
    }
    case SharedSurfaceType::EGLImageShare: {
        SharedSurface_EGLImage* eglImageSurf =
            SharedSurface_EGLImage::Cast(sharedSurf);

        eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget);
        MOZ_ASSERT(mTextureHandle);
        mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
                  : SurfaceFormat::R8G8B8X8;
        break;
    }
#ifdef XP_MACOSX
    case SharedSurfaceType::IOSurface: {
        SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf);
        mTextureHandle = glTexSurf->ConsTexture(gl());
        mTextureTarget = glTexSurf->ConsTextureTarget();
        MOZ_ASSERT(mTextureHandle);
        mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
                  : SurfaceFormat::R8G8B8X8;
        break;
    }
#endif
    case SharedSurfaceType::Basic: {
        toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData();
        MOZ_ASSERT(toUpload);
        break;
    }
    default:
        MOZ_CRASH("Invalid SharedSurface type.");
    }

    if (toUpload) {
        // mBounds seems to end up as (0,0,0,0) a lot, so don't use it?
        nsIntSize size(ThebesIntSize(toUpload->GetSize()));
        nsIntRect rect(nsIntPoint(0,0), size);
        nsIntRegion bounds(rect);
        mFormat = UploadSurfaceToTexture(gl(),
                                         toUpload,
                                         bounds,
                                         mUploadTexture,
                                         true);
        mTextureHandle = mUploadTexture;
        mTextureTarget = LOCAL_GL_TEXTURE_2D;
    }

    MOZ_ASSERT(mTextureHandle);
    gl()->fBindTexture(mTextureTarget, mTextureHandle);
    gl()->fTexParameteri(mTextureTarget,
                         LOCAL_GL_TEXTURE_WRAP_S,
                         LOCAL_GL_CLAMP_TO_EDGE);
    gl()->fTexParameteri(mTextureTarget,
                         LOCAL_GL_TEXTURE_WRAP_T,
                         LOCAL_GL_CLAMP_TO_EDGE);

    ClearCachedFilter();

    return true;
}