void UseTileTexture(CompositableTextureHostRef& aTexture, CompositableTextureSourceRef& aTextureSource, const IntRect& aUpdateRect, Compositor* aCompositor) { MOZ_ASSERT(aTexture); if (!aTexture) { return; } if (aCompositor) { aTexture->SetCompositor(aCompositor); } if (!aUpdateRect.IsEmpty()) { #ifdef MOZ_GFX_OPTIMIZE_MOBILE aTexture->Updated(nullptr); #else // We possibly upload the entire texture contents here. This is a purposeful // decision, as sub-image upload can often be slow and/or unreliable, but // we may want to reevaluate this in the future. // For !HasInternalBuffer() textures, this is likely a no-op. nsIntRegion region = aUpdateRect; aTexture->Updated(®ion); #endif } aTexture->PrepareTextureSource(aTextureSource); }
TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocator, const SurfaceDescriptorTiles& aDescriptor, const nsIntRegion& aOldPaintedRegion, Compositor* aCompositor) { mIsValid = true; mHasDoubleBufferedTiles = false; mValidRegion = aDescriptor.validRegion(); mPaintedRegion = aDescriptor.paintedRegion(); mRetainedWidth = aDescriptor.retainedWidth(); mRetainedHeight = aDescriptor.retainedHeight(); mResolution = aDescriptor.resolution(); mFrameResolution = CSSToParentLayerScale(aDescriptor.frameResolution()); if (mResolution == 0 || IsNaN(mResolution)) { // There are divisions by mResolution so this protects the compositor process // against malicious content processes and fuzzing. mIsValid = false; return; } // Combine any valid content that wasn't already uploaded nsIntRegion oldPaintedRegion(aOldPaintedRegion); oldPaintedRegion.And(oldPaintedRegion, mValidRegion); mPaintedRegion.Or(mPaintedRegion, oldPaintedRegion); bool isSameProcess = aAllocator->IsSameProcess(); const InfallibleTArray<TileDescriptor>& tiles = aDescriptor.tiles(); for(size_t i = 0; i < tiles.Length(); i++) { CompositableTextureHostRef texture; CompositableTextureHostRef textureOnWhite; const TileDescriptor& tileDesc = tiles[i]; switch (tileDesc.type()) { case TileDescriptor::TTexturedTileDescriptor : { texture = TextureHost::AsTextureHost(tileDesc.get_TexturedTileDescriptor().textureParent()); MaybeTexture onWhite = tileDesc.get_TexturedTileDescriptor().textureOnWhite(); if (onWhite.type() == MaybeTexture::TPTextureParent) { textureOnWhite = TextureHost::AsTextureHost(onWhite.get_PTextureParent()); } const TileLock& ipcLock = tileDesc.get_TexturedTileDescriptor().sharedLock(); nsRefPtr<gfxSharedReadLock> sharedLock; if (ipcLock.type() == TileLock::TShmemSection) { sharedLock = gfxShmSharedReadLock::Open(aAllocator, ipcLock.get_ShmemSection()); } else { if (!isSameProcess) { // Trying to use a memory based lock instead of a shmem based one in // the cross-process case is a bad security violation. NS_ERROR("A client process may be trying to peek at the host's address space!"); // This tells the TiledContentHost that deserialization failed so that // it can propagate the error. mIsValid = false; mRetainedTiles.Clear(); return; } sharedLock = reinterpret_cast<gfxMemorySharedReadLock*>(ipcLock.get_uintptr_t()); if (sharedLock) { // The corresponding AddRef is in TiledClient::GetTileDescriptor sharedLock.get()->Release(); } } CompositableTextureSourceRef textureSource; CompositableTextureSourceRef textureSourceOnWhite; if (texture) { texture->SetCompositor(aCompositor); texture->PrepareTextureSource(textureSource); } if (textureOnWhite) { textureOnWhite->SetCompositor(aCompositor); textureOnWhite->PrepareTextureSource(textureSourceOnWhite); } mRetainedTiles.AppendElement(TileHost(sharedLock, texture.get(), textureOnWhite.get(), textureSource.get(), textureSourceOnWhite.get())); break; } default: NS_WARNING("Unrecognised tile descriptor type"); // Fall through case TileDescriptor::TPlaceholderTileDescriptor : mRetainedTiles.AppendElement(GetPlaceholderTile()); break; } if (texture && !texture->HasInternalBuffer()) { mHasDoubleBufferedTiles = true; } } }