void TiledContentHost::RenderTile(const TiledTexture& aTile, EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, const nsIntRegion& aScreenRegion, const nsIntPoint& aTextureOffset, const nsIntSize& aTextureBounds) { MOZ_ASSERT(aTile.mDeprecatedTextureHost, "Trying to render a placeholder tile?"); RefPtr<TexturedEffect> effect = CreateTexturedEffect(aTile.mDeprecatedTextureHost, aFilter); if (!effect) { return; } if (aTile.mDeprecatedTextureHost->Lock()) { aEffectChain.mPrimaryEffect = effect; } else { return; } nsIntRegionRectIterator it(aScreenRegion); for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); Rect textureRect(rect->x - aTextureOffset.x, rect->y - aTextureOffset.y, rect->width, rect->height); effect->mTextureCoords = Rect(textureRect.x / aTextureBounds.width, textureRect.y / aTextureBounds.height, textureRect.width / aTextureBounds.width, textureRect.height / aTextureBounds.height); mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform); } mCompositor->DrawDiagnostics(DIAGNOSTIC_CONTENT|DIAGNOSTIC_TILE, aScreenRegion, aClipRect, aTransform); aTile.mDeprecatedTextureHost->Unlock(); }
void TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, const gfxRGBA* aBackgroundColor, EffectChain& aEffectChain, float aOpacity, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, nsIntRegion aVisibleRegion, gfx::Matrix4x4 aTransform) { if (!mCompositor) { NS_WARNING("Can't render tiled content host - no compositor"); return; } float resolution = aLayerBuffer.GetResolution(); gfx::Size layerScale(1, 1); // We assume that the current frame resolution is the one used in our high // precision layer buffer. Compensate for a changing frame resolution when // rendering the low precision buffer. if (aLayerBuffer.GetFrameResolution() != mTiledBuffer.GetFrameResolution()) { const CSSToParentLayerScale2D& layerResolution = aLayerBuffer.GetFrameResolution(); const CSSToParentLayerScale2D& localResolution = mTiledBuffer.GetFrameResolution(); layerScale.width = layerResolution.xScale / localResolution.xScale; layerScale.height = layerResolution.yScale / localResolution.yScale; aVisibleRegion.ScaleRoundOut(layerScale.width, layerScale.height); } // Make sure we don't render at low resolution where we have valid high // resolution content, to avoid overdraw and artifacts with semi-transparent // layers. nsIntRegion maskRegion; if (resolution != mTiledBuffer.GetResolution()) { maskRegion = mTiledBuffer.GetValidRegion(); // XXX This should be ScaleRoundIn, but there is no such function on // nsIntRegion. maskRegion.ScaleRoundOut(layerScale.width, layerScale.height); } // Make sure the resolution and difference in frame resolution are accounted // for in the layer transform. aTransform.PreScale(1/(resolution * layerScale.width), 1/(resolution * layerScale.height), 1); DiagnosticFlags componentAlphaDiagnostic = DiagnosticFlags::NO_DIAGNOSTIC; nsIntRegion compositeRegion = aLayerBuffer.GetValidRegion(); compositeRegion.AndWith(aVisibleRegion); compositeRegion.SubOut(maskRegion); IntRect visibleRect = aVisibleRegion.GetBounds(); if (compositeRegion.IsEmpty()) { return; } if (aBackgroundColor) { nsIntRegion backgroundRegion = compositeRegion; backgroundRegion.ScaleRoundOut(resolution, resolution); EffectChain effect; effect.mPrimaryEffect = new EffectSolidColor(ToColor(*aBackgroundColor)); nsIntRegionRectIterator it(backgroundRegion); for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); mCompositor->DrawQuad(graphicsRect, aClipRect, effect, 1.0, aTransform); } } for (size_t i = 0; i < aLayerBuffer.GetTileCount(); ++i) { TileHost& tile = aLayerBuffer.GetTile(i); if (tile.IsPlaceholderTile()) { continue; } TileIntPoint tilePosition = aLayerBuffer.GetPlacement().TilePosition(i); // A sanity check that catches a lot of mistakes. MOZ_ASSERT(tilePosition.x == tile.mTilePosition.x && tilePosition.y == tile.mTilePosition.y); IntPoint tileOffset = aLayerBuffer.GetTileOffset(tilePosition); nsIntRegion tileDrawRegion = IntRect(tileOffset, aLayerBuffer.GetScaledTileSize()); tileDrawRegion.AndWith(compositeRegion); if (tileDrawRegion.IsEmpty()) { continue; } tileDrawRegion.ScaleRoundOut(resolution, resolution); RenderTile(tile, aEffectChain, aOpacity, aTransform, aFilter, aClipRect, tileDrawRegion, tileOffset * resolution, aLayerBuffer.GetTileSize(), gfx::Rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height)); if (tile.mTextureHostOnWhite) { componentAlphaDiagnostic = DiagnosticFlags::COMPONENT_ALPHA; } } gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); GetCompositor()->DrawDiagnostics(DiagnosticFlags::CONTENT | componentAlphaDiagnostic, rect, aClipRect, aTransform, mFlashCounter); }
void TiledContentHost::RenderTile(const TileHost& aTile, const gfxRGBA* aBackgroundColor, EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, const nsIntRegion& aScreenRegion, const nsIntPoint& aTextureOffset, const nsIntSize& aTextureBounds) { if (aTile.IsPlaceholderTile()) { // This shouldn't ever happen, but let's fail semi-gracefully. No need // to warn, the texture update would have already caught this. return; } if (aBackgroundColor) { aEffectChain.mPrimaryEffect = new EffectSolidColor(ToColor(*aBackgroundColor)); nsIntRegionRectIterator it(aScreenRegion); for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, 1.0, aTransform); } } AutoLockTextureHost autoLock(aTile.mTextureHost); AutoLockTextureHost autoLockOnWhite(aTile.mTextureHostOnWhite); if (autoLock.Failed() || autoLockOnWhite.Failed()) { NS_WARNING("Failed to lock tile"); return; } RefPtr<TextureSource> source = aTile.mTextureHost->GetTextureSources(); RefPtr<TextureSource> sourceOnWhite = aTile.mTextureHostOnWhite ? aTile.mTextureHostOnWhite->GetTextureSources() : nullptr; if (!source || (aTile.mTextureHostOnWhite && !sourceOnWhite)) { return; } RefPtr<TexturedEffect> effect = CreateTexturedEffect(source, sourceOnWhite, aFilter, true); if (!effect) { return; } aEffectChain.mPrimaryEffect = effect; nsIntRegionRectIterator it(aScreenRegion); for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); Rect textureRect(rect->x - aTextureOffset.x, rect->y - aTextureOffset.y, rect->width, rect->height); effect->mTextureCoords = Rect(textureRect.x / aTextureBounds.width, textureRect.y / aTextureBounds.height, textureRect.width / aTextureBounds.width, textureRect.height / aTextureBounds.height); mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform); } mCompositor->DrawDiagnostics(DiagnosticFlags::CONTENT | DiagnosticFlags::TILE, aScreenRegion, aClipRect, aTransform, mFlashCounter); }
void TiledContentHost::RenderTile(TileHost& aTile, EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, const nsIntRegion& aScreenRegion, const IntPoint& aTextureOffset, const IntSize& aTextureBounds, const gfx::Rect& aVisibleRect) { MOZ_ASSERT(!aTile.IsPlaceholderTile()); AutoLockTextureHost autoLock(aTile.mTextureHost); AutoLockTextureHost autoLockOnWhite(aTile.mTextureHostOnWhite); if (autoLock.Failed() || autoLockOnWhite.Failed()) { NS_WARNING("Failed to lock tile"); return; } if (!aTile.mTextureHost->BindTextureSource(aTile.mTextureSource)) { return; } if (aTile.mTextureHostOnWhite && !aTile.mTextureHostOnWhite->BindTextureSource(aTile.mTextureSourceOnWhite)) { return; } RefPtr<TexturedEffect> effect = CreateTexturedEffect(aTile.mTextureSource, aTile.mTextureSourceOnWhite, aFilter, true, aTile.mTextureHost->GetRenderState()); if (!effect) { return; } aEffectChain.mPrimaryEffect = effect; nsIntRegionRectIterator it(aScreenRegion); for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); Rect textureRect(rect->x - aTextureOffset.x, rect->y - aTextureOffset.y, rect->width, rect->height); effect->mTextureCoords = Rect(textureRect.x / aTextureBounds.width, textureRect.y / aTextureBounds.height, textureRect.width / aTextureBounds.width, textureRect.height / aTextureBounds.height); mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform, aVisibleRect); } DiagnosticFlags flags = DiagnosticFlags::CONTENT | DiagnosticFlags::TILE; if (aTile.mTextureHostOnWhite) { flags |= DiagnosticFlags::COMPONENT_ALPHA; } mCompositor->DrawDiagnostics(flags, aScreenRegion, aClipRect, aTransform, mFlashCounter); }