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; }
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; }
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; }