already_AddRefed<ThebesLayer> ClientLayerManager::CreateThebesLayerWithHint(ThebesLayerCreationHint aHint) { NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); if ( #ifdef MOZ_B2G aHint == SCROLLABLE && #endif gfxPrefs::LayersTilesEnabled() && (AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_OPENGL || AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9 || AsShadowForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D11)) { if (gfxPrefs::LayersUseSimpleTiles()) { nsRefPtr<SimpleClientTiledThebesLayer> layer = new SimpleClientTiledThebesLayer(this); CREATE_SHADOW(Thebes); return layer.forget(); } else { nsRefPtr<ClientTiledThebesLayer> layer = new ClientTiledThebesLayer(this); CREATE_SHADOW(Thebes); return layer.forget(); } } else { nsRefPtr<ClientThebesLayer> layer = new ClientThebesLayer(this); CREATE_SHADOW(Thebes); return layer.forget(); } }
bool ClientLayerManager::AreComponentAlphaLayersEnabled() { return GetCompositorBackendType() != LayersBackend::LAYERS_BASIC && AsShadowForwarder()->SupportsComponentAlpha() && LayerManager::AreComponentAlphaLayersEnabled(); }
void CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { if (mFront) { mPrevFront = mFront; mFront = nullptr; } auto gl = aLayer->mGLContext; gl->MakeCurrent(); if (aLayer->mGLFrontbuffer) { mFront = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get()); if (mFront) mFront->Surf()->Fence(); } else { mFront = gl->Screen()->Front(); if (!mFront) return; } MOZ_ASSERT(mFront); // Alright, now sort out the IPC goop. SharedSurface* surf = mFront->Surf(); auto forwarder = GetForwarder(); auto flags = GetTextureFlags() | TextureFlags::IMMUTABLE; // Get a TexClient from our surf. RefPtr<TextureClient> newTex = TexClientFromShSurf(surf, flags); if (!newTex) { auto manager = aLayer->ClientManager(); auto shadowForwarder = manager->AsShadowForwarder(); auto layersBackend = shadowForwarder->GetCompositorBackendType(); newTex = TexClientFromReadback(surf, forwarder, flags, layersBackend); } MOZ_ASSERT(newTex); // Add the new TexClient. MOZ_ALWAYS_TRUE( AddTextureClient(newTex) ); // Remove the old TexClient. if (mFrontTex) { // remove old buffer from CompositableHost RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker(); // Hold TextureClient until transaction complete. tracker->SetTextureClient(mFrontTex); mFrontTex->SetRemoveFromCompositableTracker(tracker); // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontTex); mFrontTex = nullptr; } // Use the new TexClient. mFrontTex = newTex; forwarder->UpdatedTexture(this, mFrontTex, nullptr); forwarder->UseTexture(this, mFrontTex); }
already_AddRefed<ThebesLayer> ClientLayerManager::CreateThebesLayer() { NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); if (Preferences::GetBool("layers.force-tiles") && AsShadowForwarder()->GetCompositorBackendType() == LAYERS_OPENGL) { nsRefPtr<ClientTiledThebesLayer> layer = new ClientTiledThebesLayer(this); CREATE_SHADOW(Thebes); return layer.forget(); } else { nsRefPtr<ClientThebesLayer> layer = new ClientThebesLayer(this); CREATE_SHADOW(Thebes); return layer.forget(); } }
already_AddRefed<PersistentBufferProvider> ClientLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) { // Don't use a shared buffer provider if compositing is considered "not cheap" // because the canvas will most likely be flattened into a thebes layer instead // of being sent to the compositor, in which case rendering into shared memory // is wasteful. if (IsCompositingCheap() && gfxPrefs::PersistentBufferProviderSharedEnabled()) { RefPtr<PersistentBufferProvider> provider = PersistentBufferProviderShared::Create(aSize, aFormat, AsShadowForwarder()); if (provider) { return provider.forget(); } } return LayerManager::CreatePersistentBufferProvider(aSize, aFormat); }
bool ClientLayerManager::SupportsBackdropCopyForComponentAlpha() { const TextureFactoryIdentifier& ident = AsShadowForwarder()->GetTextureFactoryIdentifier(); return ident.mSupportsBackdropCopyForComponentAlpha; }
already_AddRefed<PersistentBufferProvider> ClientLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) { return PersistentBufferProviderShared::Create(aSize, aFormat, AsShadowForwarder()); }
void CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { auto gl = aLayer->mGLContext; gl->MakeCurrent(); RefPtr<TextureClient> newFront; if (aLayer->mGLFrontbuffer) { mShSurfClient = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->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 = aLayer->Flags() | TextureFlags::IMMUTABLE; auto manager = aLayer->ClientManager(); auto shadowForwarder = manager->AsShadowForwarder(); auto layersBackend = shadowForwarder->GetCompositorBackendType(); mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend); 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; } if (mFront) { if (mFront->GetFlags() & TextureFlags::RECYCLE) { mFront->WaitForCompositorRecycle(); } } mFront = newFront; // Add the new TexClient. MOZ_ALWAYS_TRUE( AddTextureClient(mFront) ); forwarder->UseTexture(this, mFront); }