Example #1
0
TextureClient*
CairoImage::GetTextureClient(CompositableClient *aClient)
{
  if (!aClient) {
    return nullptr;
  }

  CompositableForwarder* forwarder = aClient->GetForwarder();
  RefPtr<TextureClient> textureClient = mTextureClients.Get(forwarder->GetSerial());
  if (textureClient) {
    return textureClient;
  }

  RefPtr<SourceSurface> surface = GetAsSourceSurface();
  MOZ_ASSERT(surface);
  if (!surface) {
    return nullptr;
  }

  // gfx::BackendType::NONE means default to content backend
  textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
                                                         surface->GetSize(),
                                                         gfx::BackendType::NONE,
                                                         TextureFlags::DEFAULT);
  if (!textureClient) {
    return nullptr;
  }
  MOZ_ASSERT(textureClient->CanExposeDrawTarget());
  if (!textureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
    return nullptr;
  }

  TextureClientAutoUnlock autoUnolck(textureClient);
  {
    // We must not keep a reference to the DrawTarget after it has been unlocked.
    DrawTarget* dt = textureClient->BorrowDrawTarget();
    if (!dt) {
      return nullptr;
    }
    dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint());
  }

  mTextureClients.Put(forwarder->GetSerial(), textureClient);
  return textureClient;
}
Example #2
0
void
CanvasClientSharedSurface::UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer)
{
  GLContext* gl = nullptr;
  ClientCanvasLayer* layer = nullptr;
  AsyncCanvasRenderer* asyncRenderer = nullptr;
  if (aRenderer.constructed<ClientCanvasLayer*>()) {
    layer = aRenderer.ref<ClientCanvasLayer*>();
    gl = layer->mGLContext;
  } else {
    asyncRenderer = aRenderer.ref<AsyncCanvasRenderer*>();
    gl = asyncRenderer->mGLContext;
  }
  gl->MakeCurrent();

  RefPtr<TextureClient> newFront;

  if (layer && layer->mGLFrontbuffer) {
    mShSurfClient = CloneSurface(layer->mGLFrontbuffer.get(), layer->mFactory.get());
    if (!mShSurfClient) {
      gfxCriticalError() << "Invalid canvas front buffer";
      return;
    }
  } else {
    mShSurfClient = gl->Screen()->Front();
    if (!mShSurfClient) {
      return;
    }
  }
  MOZ_ASSERT(mShSurfClient);

  newFront = mShSurfClient;

  SharedSurface* surf = mShSurfClient->Surf();

  // Readback if needed.
  mReadbackClient = nullptr;

  auto forwarder = GetForwarder();

  bool needsReadback = (surf->mType == SharedSurfaceType::Basic);
  if (needsReadback) {
    TextureFlags flags = TextureFlags::IMMUTABLE;

    CompositableForwarder* shadowForwarder = nullptr;
    if (layer) {
      flags |= layer->Flags();
      shadowForwarder = layer->ClientManager()->AsShadowForwarder();
    } else {
      MOZ_ASSERT(asyncRenderer);
      flags |= mTextureFlags;
      shadowForwarder = GetForwarder();
    }

    auto layersBackend = shadowForwarder->GetCompositorBackendType();
    mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend);

    if (asyncRenderer) {
      // Above codes will readback the GLContext to mReadbackClient
      // in order to send frame to compositor. We copy from this
      // TextureClient directly by calling CopyFromTextureClient().
      // Therefore, if main-thread want the content of GLContext,
      // it don't have to readback it again.
      asyncRenderer->CopyFromTextureClient(mReadbackClient);
    }

    newFront = mReadbackClient;
  } else {
    mReadbackClient = nullptr;
  }

  MOZ_ASSERT(newFront);
  if (!newFront) {
    // May happen in a release build in case of memory pressure.
    gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. Size: " << aSize;
    return;
  }

  mNewFront = newFront;
}
Example #3
0
TextureClient*
CairoImage::GetTextureClient(CompositableClient *aClient)
{
  if (!aClient) {
    return nullptr;
  }

  CompositableForwarder* forwarder = aClient->GetForwarder();
  RefPtr<TextureClient> textureClient = mTextureClients.Get(forwarder->GetSerial());
  if (textureClient) {
    return textureClient;
  }

  RefPtr<SourceSurface> surface = GetAsSourceSurface();
  MOZ_ASSERT(surface);
  if (!surface) {
    return nullptr;
  }


// XXX windows' TextureClients do not hold ISurfaceAllocator,
// recycler does not work on windows.
#ifndef XP_WIN

// XXX only gonk ensure when TextureClient is recycled,
// TextureHost is not used by CompositableHost.
#ifdef MOZ_WIDGET_GONK
  RefPtr<TextureClientRecycleAllocator> recycler =
    aClient->GetTextureClientRecycler();
  if (recycler) {
    textureClient =
      recycler->CreateOrRecycleForDrawing(surface->GetFormat(),
                                          surface->GetSize(),
                                          gfx::BackendType::NONE,
                                          aClient->GetTextureFlags());
  }
#endif

#endif
  if (!textureClient) {
    // gfx::BackendType::NONE means default to content backend
    textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
                                                           surface->GetSize(),
                                                           gfx::BackendType::NONE,
                                                           TextureFlags::DEFAULT);
  }
  if (!textureClient) {
    return nullptr;
  }
  MOZ_ASSERT(textureClient->CanExposeDrawTarget());
  if (!textureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
    return nullptr;
  }

  TextureClientAutoUnlock autoUnolck(textureClient);
  {
    // We must not keep a reference to the DrawTarget after it has been unlocked.
    DrawTarget* dt = textureClient->BorrowDrawTarget();
    if (!dt) {
      return nullptr;
    }
    dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint());
  }

  mTextureClients.Put(forwarder->GetSerial(), textureClient);
  return textureClient;
}