Exemple #1
0
void
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
  GLScreenBuffer* screen = aLayer->mGLContext->Screen();
  SurfaceStream* stream = screen->Stream();

  bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
  bool bufferCreated = false;
  if (isCrossProcess) {
#ifdef MOZ_WIDGET_GONK
    SharedSurface* surf = stream->SwapConsumer();
    if (!surf) {
      printf_stderr("surf is null post-SwapConsumer!\n");
      return;
    }

    if (surf->Type() != SharedSurfaceType::Gralloc) {
      printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!");
      MOZ_ASSERT(false);
      return;
    }

    SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);

    GrallocTextureClientOGL* grallocTextureClient =
      static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient());

    // If IPDLActor is null means this TextureClient didn't AddTextureClient yet
    if (!grallocTextureClient->GetIPDLActor()) {
      grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags);
      AddTextureClient(grallocTextureClient);
    }

    if (grallocTextureClient->GetIPDLActor()) {
      GetForwarder()->UseTexture(this, grallocTextureClient);
    }
#else
    printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
    MOZ_ASSERT(false);
#endif
  } else {
    if (!mBuffer) {
      StreamTextureClientOGL* textureClient =
        new StreamTextureClientOGL(mTextureInfo.mTextureFlags);
      textureClient->InitWith(stream);
      mBuffer = textureClient;
      bufferCreated = true;
    }

    if (bufferCreated && !AddTextureClient(mBuffer)) {
      mBuffer = nullptr;
    }

    if (mBuffer) {
      GetForwarder()->UseTexture(this, mBuffer);
    }
  }

  aLayer->Painted();
}
Exemple #2
0
void
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
  if (!mTextureClient) {
    mTextureClient = CreateTextureClient(TEXTURE_STREAM_GL);
    MOZ_ASSERT(mTextureClient, "Failed to create texture client");
  }

  NS_ASSERTION(aLayer->mGLContext, "CanvasClientSurfaceStream should only be used with GL canvases");

  // the content type won't be used
  mTextureClient->EnsureAllocated(aSize, gfxASurface::CONTENT_COLOR);

  GLScreenBuffer* screen = aLayer->mGLContext->Screen();
  SurfaceStream* stream = screen->Stream();

  bool isCrossProcess = !(XRE_GetProcessType() == GoannaProcessType_Default);
  if (isCrossProcess) {
    // swap staging -> consumer so we can send it to the compositor
    SharedSurface* surf = stream->SwapConsumer();
    if (!surf) {
      printf_stderr("surf is null post-SwapConsumer!\n");
      return;
    }

#ifdef MOZ_WIDGET_GONK
    if (surf->Type() != SharedSurfaceType::Gralloc) {
      printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!");
      return;
    }

    SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);
    mTextureClient->SetDescriptor(grallocSurf->GetDescriptor());
#else
    printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
    MOZ_ASSERT(false);
#endif
    mNeedsUpdate = true;
  } else {
    SurfaceStreamHandle handle = stream->GetShareHandle();
    SurfaceDescriptor *desc = mTextureClient->GetDescriptor();
    if (desc->type() != SurfaceDescriptor::TSurfaceStreamDescriptor ||
        desc->get_SurfaceStreamDescriptor().handle() != handle) {
      *desc = SurfaceStreamDescriptor(handle, false);

      // Ref this so the SurfaceStream doesn't disappear unexpectedly. The
      // Compositor will need to unref it when finished.
      aLayer->mGLContext->AddRef();
      
      mNeedsUpdate = true;
    }
  }

  aLayer->Painted();
}
void
DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
  if (!mDeprecatedTextureClient) {
    mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_STREAM_GL,
                                                             aLayer->GetSurfaceMode() == SurfaceMode::SURFACE_OPAQUE
                                                               ? gfxContentType::COLOR
                                                               : gfxContentType::COLOR_ALPHA);
    MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client");
  }

  NS_ASSERTION(aLayer->mGLContext, "CanvasClientSurfaceStream should only be used with GL canvases");

  // the content type won't be used
  mDeprecatedTextureClient->EnsureAllocated(aSize, gfxContentType::COLOR);

  GLScreenBuffer* screen = aLayer->mGLContext->Screen();
  SurfaceStream* stream = nullptr;

  if (aLayer->mStream) {
    stream = aLayer->mStream;
    stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
    stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
  } else {
    stream = screen->Stream();
  }

  bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
  if (isCrossProcess) {
    // swap staging -> consumer so we can send it to the compositor
    SharedSurface* surf = stream->SwapConsumer();
    if (!surf) {
      printf_stderr("surf is null post-SwapConsumer!\n");
      return;
    }

#ifdef MOZ_WIDGET_GONK
    if (surf->Type() != SharedSurfaceType::Gralloc) {
      printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!");
      return;
    }

    SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);
    //XXX todo
    //mDeprecatedTextureClient->SetDescriptor(grallocSurf->GetDescriptor());
#else
    printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
    MOZ_ASSERT(false);
#endif
  } else {
    SurfaceStreamHandle handle = stream->GetShareHandle();
    mDeprecatedTextureClient->SetDescriptor(SurfaceStreamDescriptor(handle, false));

    // Bug 894405
    //
    // Ref this so the SurfaceStream doesn't disappear unexpectedly. The
    // Compositor will need to unref it when finished.
    aLayer->mGLContext->AddRef();
  }

  aLayer->Painted();
}
Exemple #4
0
void
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
  aLayer->mGLContext->MakeCurrent();
  GLScreenBuffer* screen = aLayer->mGLContext->Screen();
  SurfaceStream* stream = nullptr;

  if (aLayer->mStream) {
    stream = aLayer->mStream;

    // Copy our current surface to the current producer surface in our stream, then
    // call SwapProducer to make a new buffer ready.
    stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
    stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
  } else {
    stream = screen->Stream();
  }

  bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
  bool bufferCreated = false;
  if (isCrossProcess) {
#ifdef MOZ_WIDGET_GONK
    SharedSurface* surf = stream->SwapConsumer();
    if (!surf) {
      printf_stderr("surf is null post-SwapConsumer!\n");
      return;
    }

    if (surf->Type() != SharedSurfaceType::Gralloc) {
      printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!");
      MOZ_ASSERT(false);
      return;
    }

    SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);

    RefPtr<GrallocTextureClientOGL> grallocTextureClient =
      static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient());

    // If IPDLActor is null means this TextureClient didn't AddTextureClient yet
    if (!grallocTextureClient->GetIPDLActor()) {
      grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags);
      AddTextureClient(grallocTextureClient);
    }

    if (grallocTextureClient->GetIPDLActor()) {
      UseTexture(grallocTextureClient);
    }

    if (mBuffer && CompositorChild::ChildProcessHasCompositor()) {
      // remove old buffer from CompositableHost
      RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker();
      // Hold TextureClient until transaction complete.
      tracker->SetTextureClient(mBuffer);
      mBuffer->SetRemoveFromCompositableTracker(tracker);
      // RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
      GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mBuffer);
    }
    mBuffer = grallocTextureClient;
#else
    printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
    MOZ_ASSERT(false);
#endif
  } else {
    if (!mBuffer) {
      StreamTextureClientOGL* textureClient =
        new StreamTextureClientOGL(mTextureInfo.mTextureFlags);
      textureClient->InitWith(stream);
      mBuffer = textureClient;
      bufferCreated = true;
    }

    if (bufferCreated && !AddTextureClient(mBuffer)) {
      mBuffer = nullptr;
    }

    if (mBuffer) {
      GetForwarder()->UseTexture(this, mBuffer);
    }
  }

  aLayer->Painted();
}
void
ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
                                  const nsIntPoint& aOffset)
{
  if (!mTexImage &&
      !IsValidSharedTexDescriptor(mFrontBufferDescriptor) &&
      !IsValidSurfaceStreamDescriptor(mFrontBufferDescriptor))
  {
    return;
  }

  if (mOGLManager->CompositingDisabled()) {
    return;
  }
  mOGLManager->MakeCurrent();
  gl()->EmptyTexGarbageBin();
  //ScopedBindTexture autoTex(gl());

  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
  SurfaceStream* surfStream = nullptr;
  SharedSurface* sharedSurf = nullptr;
  if (IsValidSurfaceStreamDescriptor(mFrontBufferDescriptor)) {
    const SurfaceStreamDescriptor& streamDesc =
        mFrontBufferDescriptor.get_SurfaceStreamDescriptor();

    surfStream = SurfaceStream::FromHandle(streamDesc.handle());
    MOZ_ASSERT(surfStream);

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

    gfxImageSurface* toUpload = nullptr;
    switch (sharedSurf->Type()) {
      case SharedSurfaceType::GLTextureShare: {
        mCurTexture = SharedSurface_GLTexture::Cast(sharedSurf)->Texture();
        MOZ_ASSERT(mCurTexture);
        mShaderType = sharedSurf->HasAlpha() ? RGBALayerProgramType
                                             : RGBXLayerProgramType;
        break;
      }
      case SharedSurfaceType::EGLImageShare: {
        SharedSurface_EGLImage* eglImageSurf =
            SharedSurface_EGLImage::Cast(sharedSurf);

        mCurTexture = eglImageSurf->AcquireConsumerTexture(gl());
        if (!mCurTexture) {
          toUpload = eglImageSurf->GetPixels();
          MOZ_ASSERT(toUpload);
        } else {
          mShaderType = sharedSurf->HasAlpha() ? RGBALayerProgramType
                                               : RGBXLayerProgramType;
        }
        break;
      }
      case SharedSurfaceType::Basic: {
        toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData();
        MOZ_ASSERT(toUpload);
        break;
      }
      default:
        MOZ_NOT_REACHED("Invalid SharedSurface type.");
        return;
    }

    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);
      mShaderType = gl()->UploadSurfaceToTexture(toUpload,
                                                 bounds,
                                                 mUploadTexture,
                                                 true);
      mCurTexture = mUploadTexture;
    }

    MOZ_ASSERT(mCurTexture);
    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mCurTexture);
    gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D,
                         LOCAL_GL_TEXTURE_WRAP_S,
                         LOCAL_GL_CLAMP_TO_EDGE);
    gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D,
                         LOCAL_GL_TEXTURE_WRAP_T,
                         LOCAL_GL_CLAMP_TO_EDGE);
  } else if (mTexImage) {
    mShaderType = mTexImage->GetShaderProgramType();
  } else {
    MOZ_NOT_REACHED("What can we do?");
    return;
  }

  ShaderProgramOGL* program = mOGLManager->GetProgram(mShaderType, GetMaskLayer());

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

  if (surfStream) {
    MOZ_ASSERT(sharedSurf);

    gl()->ApplyFilterToBoundTexture(filter);
    program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), sharedSurf->Size()));

    mOGLManager->BindAndDrawQuad(program, mNeedsYFlip);

    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());
    }
  }
}
bool
SurfaceStreamHostOGL::Lock()
{
  mGL->MakeCurrent();
  SurfaceStream* surfStream = nullptr;
  SharedSurface* sharedSurf = nullptr;
  const SurfaceStreamDescriptor& streamDesc =
    mBuffer->get_SurfaceStreamDescriptor();

  surfStream = SurfaceStream::FromHandle(streamDesc.handle());
  MOZ_ASSERT(surfStream);

  sharedSurf = surfStream->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();
      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);
      if (!mTextureHandle) {
        toUpload = eglImageSurf->GetPixels();
        MOZ_ASSERT(toUpload);
      } else {
        mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8
                                         : FORMAT_R8G8B8X8;
      }
      break;
    }
    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;
  }

  MOZ_ASSERT(mTextureHandle);
  mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle);
  mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D,
                      LOCAL_GL_TEXTURE_WRAP_S,
                      LOCAL_GL_CLAMP_TO_EDGE);
  mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D,
                      LOCAL_GL_TEXTURE_WRAP_T,
                      LOCAL_GL_CLAMP_TO_EDGE);
  return true;
}