void
SharedDeprecatedTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage,
                                       nsIntRegion* aRegion)
{
  NS_ASSERTION(aImage.type() == SurfaceDescriptor::TSharedTextureDescriptor,
              "Invalid descriptor");

  SharedTextureDescriptor texture = aImage.get_SharedTextureDescriptor();

  SharedTextureHandle newHandle = texture.handle();
  nsIntSize size = texture.size();
  mSize = gfx::IntSize(size.width, size.height);
  if (texture.inverted()) {
    mFlags |= TEXTURE_NEEDS_Y_FLIP;
  }

  if (mSharedHandle && mSharedHandle != newHandle) {
    mGL->ReleaseSharedHandle(mShareType, mSharedHandle);
  }

  mShareType = texture.shareType();
  mSharedHandle = newHandle;

  GLContext::SharedHandleDetails handleDetails;
  if (mSharedHandle && mGL->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
    mTextureTarget = handleDetails.mTarget;
    mFormat = handleDetails.mTextureFormat;
  }
}
 void DestroyBackBuffer()
 {
     if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor) {
         SharedTextureDescriptor handle = mBackBuffer.get_SharedTextureDescriptor();
         if (mGLContext && handle.handle()) {
             mGLContext->ReleaseSharedHandle(handle.shareType(), handle.handle());
             mBackBuffer = SurfaceDescriptor();
         }
     } else if (IsSurfaceDescriptorValid(mBackBuffer)) {
         BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
         mBackBuffer = SurfaceDescriptor();
     }
 }
void
ShadowCanvasLayerOGL::DestroyFrontBuffer()
{
  mTexImage = nsnull;
  if (mTexture) {
    gl()->MakeCurrent();
    gl()->fDeleteTextures(1, &mTexture);
  }
  if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
    SharedTextureDescriptor texDescriptor = mFrontBufferDescriptor.get_SharedTextureDescriptor();
    gl()->ReleaseSharedHandle(texDescriptor.shareType(), texDescriptor.handle());
    mFrontBufferDescriptor = SurfaceDescriptor();
  }
}
bool
ShadowImageLayerOGL::Init(const SharedImage& aFront)
{
  if (aFront.type() == SharedImage::TSurfaceDescriptor) {
    SurfaceDescriptor surface = aFront.get_SurfaceDescriptor();
    if (surface.type() == SurfaceDescriptor::TSharedTextureDescriptor) {
      SharedTextureDescriptor texture = surface.get_SharedTextureDescriptor();
      mSize = texture.size();
      mSharedHandle = texture.handle();
      mShareType = texture.shareType();
      mInverted = texture.inverted();
    } else {
      AutoOpenSurface autoSurf(OPEN_READ_ONLY, surface);
      mSize = autoSurf.Size();
      mTexImage = gl()->CreateTextureImage(nsIntSize(mSize.width, mSize.height),
                                           autoSurf.ContentType(),
                                           LOCAL_GL_CLAMP_TO_EDGE,
                                           mForceSingleTile
                                            ? TextureImage::ForceSingleTile
                                            : TextureImage::NoFlags);
    }
  } else {
    YUVImage yuv = aFront.get_YUVImage();

    AutoOpenSurface surfY(OPEN_READ_ONLY, yuv.Ydata());
    AutoOpenSurface surfU(OPEN_READ_ONLY, yuv.Udata());

    mSize = surfY.Size();
    mCbCrSize = surfU.Size();

    if (!mYUVTexture[0].IsAllocated()) {
      mYUVTexture[0].Allocate(gl());
      mYUVTexture[1].Allocate(gl());
      mYUVTexture[2].Allocate(gl());
    }

    NS_ASSERTION(mYUVTexture[0].IsAllocated() &&
                 mYUVTexture[1].IsAllocated() &&
                 mYUVTexture[2].IsAllocated(),
                 "Texture allocation failed!");

    gl()->MakeCurrent();
    SetClamping(gl(), mYUVTexture[0].GetTextureID());
    SetClamping(gl(), mYUVTexture[1].GetTextureID());
    SetClamping(gl(), mYUVTexture[2].GetTextureID());
    return true;
  }
  return false;
}
void
ShadowImageLayerOGL::Swap(const SharedImage& aNewFront,
                          SharedImage* aNewBack)
{
  if (!mDestroyed) {

    if (aNewFront.type() == SharedImage::TSharedImageID) {
      // We are using ImageBridge protocol. The image data will be queried at render
      // time in the parent side.
      uint64_t newID = aNewFront.get_SharedImageID().id();
      if (newID != mImageContainerID) {
        mImageContainerID = newID;
        mImageVersion = 0;
      }
    } else if (aNewFront.type() == SharedImage::TSurfaceDescriptor) {
      SurfaceDescriptor surface = aNewFront.get_SurfaceDescriptor();

      if (surface.type() == SurfaceDescriptor::TSharedTextureDescriptor) {
        SharedTextureDescriptor texture = surface.get_SharedTextureDescriptor();

        SharedTextureHandle newHandle = texture.handle();
        mSize = texture.size();
        mInverted = texture.inverted();

        if (mSharedHandle && newHandle != mSharedHandle)
          gl()->ReleaseSharedHandle(mShareType, mSharedHandle);

        mSharedHandle = newHandle;
        mShareType = texture.shareType();
      } else {
        AutoOpenSurface surf(OPEN_READ_ONLY, surface);
        gfxIntSize size = surf.Size();
        if (mSize != size || !mTexImage ||
            mTexImage->GetContentType() != surf.ContentType()) {
          Init(aNewFront);
        }
        // XXX this is always just ridiculously slow
        nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height));
        mTexImage->DirectUpdate(surf.Get(), updateRegion);
      }
    } else {
      const YUVImage& yuv = aNewFront.get_YUVImage();
      UploadSharedYUVToTexture(yuv);
    }
  }

  *aNewBack = aNewFront;
}
void
ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
                                  const nsIntPoint& aOffset)
{
  if (!mTexImage && !IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
    return;
  }

  if (mOGLManager->CompositingDisabled()) {
    return;
  }
  mOGLManager->MakeCurrent();

  gfx3DMatrix effectiveTransform = GetEffectiveTransform();
  gfxPattern::GraphicsFilter filter = mFilter;
#ifdef ANDROID
  // Bug 691354
  // Using the LINEAR filter we get unexplained artifacts.
  // Use NEAREST when no scaling is required.
  gfxMatrix matrix;
  bool is2D = GetEffectiveTransform().Is2D(&matrix);
  if (is2D && !matrix.HasNonTranslationOrFlip()) {
    filter = gfxPattern::FILTER_NEAREST;
  }
#endif

  ShaderProgramOGL *program;
  if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
    program = mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(),
                                                true,
                                                GetMaskLayer() ? Mask2d : MaskNone);
  } else {
    program = mOGLManager->GetProgram(mTexImage->GetShaderProgramType(),
                                      GetMaskLayer());
  }

  program->Activate();
  program->SetLayerTransform(effectiveTransform);
  program->SetLayerOpacity(GetEffectiveOpacity());
  program->SetRenderOffset(aOffset);
  program->SetTextureUnit(0);
  program->LoadMask(GetMaskLayer());

  if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
    // Shared texture handle rendering path, single texture rendering
    SharedTextureDescriptor texDescriptor = mFrontBufferDescriptor.get_SharedTextureDescriptor();
    gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
    if (!gl()->AttachSharedHandle(texDescriptor.shareType(), texDescriptor.handle())) {
      NS_ERROR("Failed to attach shared texture handle");
      return;
    }
    gl()->ApplyFilterToBoundTexture(filter);
    program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), texDescriptor.size()));
    mOGLManager->BindAndDrawQuad(program, mNeedsYFlip);
    gl()->DetachSharedHandle(texDescriptor.shareType(), texDescriptor.handle());
    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
  } else {
    // Tiled texture image rendering path
    mTexImage->SetFilter(filter);
    mTexImage->BeginTileIteration();
    if (gl()->CanUploadNonPowerOfTwo()) {
      do {
        TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
        program->SetLayerQuadRect(mTexImage->GetTileRect());
        mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles?
      } while (mTexImage->NextTile());
    } else {
      do {
        TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
        program->SetLayerQuadRect(mTexImage->GetTileRect());
        // We can't use BindAndDrawQuad because that always uploads the whole texture from 0.0f -> 1.0f
        // in x and y. We use BindAndDrawQuadWithTextureRect to actually draw a subrect of the texture
        // We need to reset the origin to 0,0 from the tile rect because the tile originates at 0,0 in the
        // actual texture, even though its origin in the composed (tiled) texture is not 0,0
        // FIXME: we need to handle mNeedsYFlip, Bug #728625
        mOGLManager->BindAndDrawQuadWithTextureRect(program,
                                                    nsIntRect(0, 0, mTexImage->GetTileRect().width,
                                                                    mTexImage->GetTileRect().height),
                                                    mTexImage->GetTileRect().Size(),
                                                    mTexImage->GetWrapMode(),
                                                    mNeedsYFlip);
      } while (mTexImage->NextTile());
    }
  }
}