зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1295094 - Part 6. Implement CreateBlendTarget and BlendToTarget. r=mstange
MozReview-Commit-ID: 3C3hlje0QEw --HG-- extra : rebase_source : aaf3527cd3e3fcf12efa20d91a5233c9828d2f1d
This commit is contained in:
Родитель
8afbe7e2c0
Коммит
9bf4d9c5cd
|
@ -703,6 +703,49 @@ SetupContextMatrix(const nsSVGIntegrationUtils::PaintFramesParams& aParams,
|
||||||
aParams.ctx.SetMatrix(aParams.ctx.CurrentMatrix().Translate(devPixelOffsetToUserSpace));
|
aParams.ctx.SetMatrix(aParams.ctx.CurrentMatrix().Translate(devPixelOffsetToUserSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<gfxContext>
|
||||||
|
CreateBlendTarget(const nsSVGIntegrationUtils::PaintFramesParams& aParams,
|
||||||
|
IntPoint& aTargetOffset)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aParams.frame->StyleEffects()->mMixBlendMode !=
|
||||||
|
NS_STYLE_BLEND_NORMAL);
|
||||||
|
|
||||||
|
// Create a temporary context to draw to so we can blend it back with
|
||||||
|
// another operator.
|
||||||
|
IntRect drawRect = ComputeClipExtsInDeviceSpace(aParams.ctx);
|
||||||
|
|
||||||
|
RefPtr<DrawTarget> targetDT = aParams.ctx.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8);
|
||||||
|
if (!targetDT || !targetDT->IsValid()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<gfxContext> target = gfxContext::CreateOrNull(targetDT);
|
||||||
|
MOZ_ASSERT(target); // already checked the draw target above
|
||||||
|
target->SetMatrix(aParams.ctx.CurrentMatrix() *
|
||||||
|
gfxMatrix::Translation(-drawRect.TopLeft()));
|
||||||
|
aTargetOffset = drawRect.TopLeft();
|
||||||
|
|
||||||
|
return target.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
BlendToTarget(const nsSVGIntegrationUtils::PaintFramesParams& aParams,
|
||||||
|
gfxContext* aTarget, const IntPoint& aTargetOffset)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aParams.frame->StyleEffects()->mMixBlendMode !=
|
||||||
|
NS_STYLE_BLEND_NORMAL);
|
||||||
|
|
||||||
|
RefPtr<DrawTarget> targetDT = aTarget->GetDrawTarget();
|
||||||
|
RefPtr<SourceSurface> targetSurf = targetDT->Snapshot();
|
||||||
|
|
||||||
|
gfxContext& context = aParams.ctx;
|
||||||
|
gfxContextAutoSaveRestore save(&context);
|
||||||
|
context.SetMatrix(gfxMatrix()); // This will be restored right after.
|
||||||
|
RefPtr<gfxPattern> pattern = new gfxPattern(targetSurf, Matrix::Translation(aTargetOffset.x, aTargetOffset.y));
|
||||||
|
context.SetPattern(pattern);
|
||||||
|
context.Paint();
|
||||||
|
}
|
||||||
|
|
||||||
DrawResult
|
DrawResult
|
||||||
nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
||||||
{
|
{
|
||||||
|
@ -782,22 +825,13 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
||||||
!shouldApplyClipPath && !shouldApplyBasicShape);
|
!shouldApplyClipPath && !shouldApplyBasicShape);
|
||||||
|
|
||||||
// These are used if we require a temporary surface for a custom blend mode.
|
// These are used if we require a temporary surface for a custom blend mode.
|
||||||
RefPtr<gfxContext> target = &aParams.ctx;
|
|
||||||
IntPoint targetOffset;
|
IntPoint targetOffset;
|
||||||
|
RefPtr<gfxContext> target =
|
||||||
if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
(aParams.frame->StyleEffects()->mMixBlendMode == NS_STYLE_BLEND_NORMAL)
|
||||||
// Create a temporary context to draw to so we can blend it back with
|
? RefPtr<gfxContext>(&aParams.ctx).forget()
|
||||||
// another operator.
|
: CreateBlendTarget(aParams, targetOffset);
|
||||||
IntRect drawRect = ComputeClipExtsInDeviceSpace(context);
|
if (!target) {
|
||||||
|
return DrawResult::TEMPORARY_ERROR;
|
||||||
RefPtr<DrawTarget> targetDT = context.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8);
|
|
||||||
if (!targetDT || !targetDT->IsValid()) {
|
|
||||||
return DrawResult::TEMPORARY_ERROR;
|
|
||||||
}
|
|
||||||
target = gfxContext::CreateOrNull(targetDT);
|
|
||||||
MOZ_ASSERT(target); // already checked the draw target above
|
|
||||||
target->SetMatrix(context.CurrentMatrix() * gfxMatrix::Translation(-drawRect.TopLeft()));
|
|
||||||
targetOffset = drawRect.TopLeft();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldGenerateMask = (opacity != 1.0f || shouldGenerateClipMaskLayer ||
|
bool shouldGenerateMask = (opacity != 1.0f || shouldGenerateClipMaskLayer ||
|
||||||
|
@ -882,16 +916,9 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
||||||
context.Restore();
|
context.Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
if (aParams.frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||||
RefPtr<DrawTarget> targetDT = target->GetDrawTarget();
|
MOZ_ASSERT(target != &aParams.ctx);
|
||||||
target = nullptr;
|
BlendToTarget(aParams, target, targetOffset);
|
||||||
RefPtr<SourceSurface> targetSurf = targetDT->Snapshot();
|
|
||||||
|
|
||||||
gfxContextAutoSaveRestore save(&context);
|
|
||||||
context.SetMatrix(gfxMatrix()); // This will be restored right after.
|
|
||||||
RefPtr<gfxPattern> pattern = new gfxPattern(targetSurf, Matrix::Translation(targetOffset.x, targetOffset.y));
|
|
||||||
context.SetPattern(pattern);
|
|
||||||
context.Paint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче